com.notifier.dispatchers.QueuedDispatcher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of notifier Show documentation
Show all versions of notifier Show documentation
A generic event dispatching library
The newest version!
package com.notifier.dispatchers;
import com.notifier.Event;
import com.notifier.Listener;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class QueuedDispatcher implements EventDispatcher {
private final Queue mEvents;
public QueuedDispatcher(Queue events) {
mEvents = events;
}
public static QueuedDispatcher withBlockingHandler() {
BlockingQueue events = new LinkedBlockingQueue<>();
QueuedDispatcher dispatcher = new QueuedDispatcher(events);
Thread runThread = new Thread(new BlockingTask(events), dispatcher.toString()+"-handling thread");
runThread.setDaemon(true);
runThread.start();
return dispatcher;
}
public static QueuedDispatcher withBlockingHandler(Executor executor) {
BlockingQueue events = new LinkedBlockingQueue<>();
executor.execute(new BlockingTask(events));
return new QueuedDispatcher(events);
}
public static QueuedDispatcher withPeriodicHandler(Consumer taskExecutor, long maxPeriodRunTimeMs) {
Queue events = new LinkedList<>();
taskExecutor.accept(new PeriodicTask(events, maxPeriodRunTimeMs));
return new QueuedDispatcher(events);
}
public static QueuedDispatcher withPeriodicHandler(ScheduledExecutorService executorService, long periodMs, long maxPeriodRunTimeMs) {
Queue events = new LinkedList<>();
executorService.scheduleAtFixedRate(new PeriodicTask(events, maxPeriodRunTimeMs), periodMs, periodMs, TimeUnit.MILLISECONDS);
return new QueuedDispatcher(events);
}
public static QueuedDispatcher withPeriodicHandler(ScheduledExecutorService executorService, long periodMs) {
return withPeriodicHandler(executorService, periodMs, Math.min(periodMs / 2, 50));
}
@Override
public void dispatch(Collection listeners, Predicate listenerFilter, Event event, BiConsumer listenerCall) {
for (Listener listener : listeners) {
if (listenerFilter.test(listener)) {
mEvents.add(new DispatchingTask(listener, event, listenerCall));
}
}
}
private static class BlockingTask implements Runnable {
private final BlockingQueue mQueue;
private BlockingTask(BlockingQueue queue) {
mQueue = queue;
}
@Override
public void run() {
try {
while (!Thread.interrupted()) {
Runnable runnable = mQueue.poll(1, TimeUnit.SECONDS);
if (runnable != null) {
runnable.run();
}
}
} catch (InterruptedException e) {
}
}
}
private static class PeriodicTask implements Runnable {
private final Queue mQueue;
private final long mMaxPeriodRunTimeMs;
private PeriodicTask(Queue queue, long maxPeriodRunTimeMs) {
mQueue = queue;
mMaxPeriodRunTimeMs = maxPeriodRunTimeMs;
}
@Override
public void run() {
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < mMaxPeriodRunTimeMs) {
Runnable runnable = mQueue.poll();
if (runnable == null) {
break;
}
runnable.run();
}
}
}
}