
goja.core.libs.event.ArchivedEventStream Maven / Gradle / Ivy
The newest version!
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2013-2014 sagyf Yang. The Four Group.
*/
package goja.core.libs.event;
import goja.core.libs.Promise;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* .
*
* @author sagyf yang
* @version 1.0 2014-09-11 13:25
* @since JDK 1.6
*/
public class ArchivedEventStream {
final int archiveSize;
final ConcurrentLinkedQueue> events = new ConcurrentLinkedQueue>();
final List> waiting = Collections.synchronizedList(new ArrayList>());
final List> pipedStreams = new ArrayList>();
public ArchivedEventStream(int archiveSize) {
this.archiveSize = archiveSize;
}
public synchronized EventStream eventStream() {
final EventStream stream = new EventStream(archiveSize);
for (IndexedEvent event : events) {
stream.publish(event.data);
}
pipedStreams.add(stream);
return stream;
}
public synchronized Promise>> nextEvents(long lastEventSeen) {
FilterTask filter = new FilterTask(lastEventSeen);
waiting.add(filter);
notifyNewEvent();
return filter;
}
public synchronized List availableEvents(long lastEventSeen) {
List result = new ArrayList();
for (IndexedEvent event : events) {
if (event.id > lastEventSeen) {
result.add(event);
}
}
return result;
}
public List archive() {
List result = new ArrayList();
for (IndexedEvent event : events) {
result.add(event.data);
}
return result;
}
public synchronized void publish(T event) {
if (events.size() >= archiveSize) {
events.poll();
}
events.offer(new IndexedEvent(event));
notifyNewEvent();
for (EventStream eventStream : pipedStreams) {
eventStream.publish(event);
}
}
void notifyNewEvent() {
for (ListIterator> it = waiting.listIterator(); it.hasNext(); ) {
FilterTask filter = it.next();
for (IndexedEvent event : events) {
filter.propose(event);
}
if (filter.trigger()) {
it.remove();
}
}
}
static class FilterTask extends Promise>> {
final Long lastEventSeen;
final List> newEvents = new ArrayList>();
public FilterTask(Long lastEventSeen) {
this.lastEventSeen = lastEventSeen;
}
public void propose(IndexedEvent event) {
if (event.id > lastEventSeen) {
newEvents.add(event);
}
}
public boolean trigger() {
if (newEvents.isEmpty()) {
return false;
}
invoke(newEvents);
return true;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy