com.ziqni.admin.sdk.eventbus.ZiqniSimpleEventBus Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ziqni-admin-sdk Show documentation
Show all versions of ziqni-admin-sdk Show documentation
ZIQNI Admin SDK Java Client
/*
* Copyright (c) 2024. ZIQNI LTD registered in England and Wales, company registration number-09693684
*/
package com.ziqni.admin.sdk.eventbus;
import com.ziqni.admin.sdk.streaming.stomp.StompHeaders;
import com.ziqni.admin.sdk.streaming.stomp.StompOverWebSocketLifeCycle.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.*;
import java.util.function.Consumer;
/**
* A simple event bus implementation
*/
public class ZiqniSimpleEventBus {
private static final Logger logger = LoggerFactory.getLogger(ZiqniSimpleEventBus.class);
/**
* The task queue to ensure events are processed in order
*/
public final LinkedBlockingDeque tasks;
/**
* The executor service to process events
*/
private final ExecutorService executor;
/**
* The map of event type to subscribers
*/
private final ConcurrentHashMap, MessageConsumers>> subscribers;
/**
* Create a new ZiqniSimpleEventBus
*/
public ZiqniSimpleEventBus() {
this.subscribers = new ConcurrentHashMap<>();
this.tasks = new LinkedBlockingDeque<>();
this.executor = new ThreadPoolExecutor(1, 4, 0L, TimeUnit.MILLISECONDS, tasks);
}
/**
* Post a message to all subscribers
* @param message the message to post
*/
public void post(Object message) {
if(message == null) {
throw new IllegalArgumentException("Message cannot be null");
}
if(subscribers.isEmpty()) {
return;
}
final MessageConsumers> found = subscribers.get(message.getClass());
if (found != null) {
found.notifyAll(message);
}
}
/**
* Register a subscriber for events of its class type
* @param type the event type
* @param consumer the subscriber
* @param the event type
*/
public void register(Class type, Consumer consumer) {
subscribers.compute(type, (key, value) -> {
if (value == null) {
value = new MessageConsumers<>(type, executor);
}
value.add(consumer);
return value;
});
}
/**
* Unregister a subscriber
* @param consumer the subscriber to unregister
* @param the event type
*/
public void unregister(Consumer consumer) {
subscribers.values().forEach(messageConsumers ->
messageConsumers.consumers.remove(consumer)
);
}
/**
* MessageConsumers class to hold the event type and its subscribers
* @param the event type
*/
public static class MessageConsumers {
final Class type;
final Set> consumers = new HashSet<>();
private final ExecutorService ex;
public MessageConsumers(Class type, ExecutorService ex) {
this.ex = ex;
this.type = type;
}
public void notifyAll(Object event) {
if (type.isInstance(event)) {
consumers.forEach(subscriber ->
ex.submit( () -> handle(subscriber,type.cast(event)) )
);
} else {
throw new IllegalArgumentException(
"Invalid event type. Expected: " + type.getName() + ", but got: " + event.getClass().getName());
}
}
private void handle(Consumer subscriber, T event) {
try {
subscriber.accept(event);
}
catch (Throwable t) {
logger.error("Error handling event", t);
}
}
@SuppressWarnings("unchecked")
public void add(Consumer> subscriber) {
// Wrap the unchecked cast with a type check
if (Objects.nonNull(subscriber)) {
consumers.add(event -> ((Consumer
© 2015 - 2025 Weber Informatics LLC | Privacy Policy