use of org.ballerinalang.siddhi.core.event.stream.StreamEvent in project ballerina by ballerina-lang.
the class ExternalTimeBatchWindowProcessor method process.
/**
* Here an assumption is taken:
* Parameter: timestamp: The time which the window determines as current time and will act upon,
* the value of this parameter should be monotonically increasing.
* from https://docs.wso2.com/display/CEP400/Inbuilt+Windows#InbuiltWindows-externalTime
*/
@Override
protected void process(ComplexEventChunk<StreamEvent> streamEventChunk, Processor nextProcessor, StreamEventCloner streamEventCloner) {
// event incoming trigger process. No events means no action
if (streamEventChunk.getFirst() == null) {
return;
}
List<ComplexEventChunk<StreamEvent>> complexEventChunks = new ArrayList<ComplexEventChunk<StreamEvent>>();
synchronized (this) {
initTiming(streamEventChunk.getFirst());
StreamEvent nextStreamEvent = streamEventChunk.getFirst();
while (nextStreamEvent != null) {
StreamEvent currStreamEvent = nextStreamEvent;
nextStreamEvent = nextStreamEvent.getNext();
if (currStreamEvent.getType() == ComplexEvent.Type.TIMER) {
if (lastScheduledTime <= currStreamEvent.getTimestamp()) {
// implies that there have not been any more events after this schedule has been done.
if (!flushed) {
flushToOutputChunk(streamEventCloner, complexEventChunks, lastCurrentEventTime, true);
flushed = true;
} else {
if (currentEventChunk.getFirst() != null) {
appendToOutputChunk(streamEventCloner, complexEventChunks, lastCurrentEventTime, true);
}
}
// rescheduling to emit the current batch after expiring it if no further events arrive.
lastScheduledTime = siddhiAppContext.getTimestampGenerator().currentTime() + schedulerTimeout;
scheduler.notifyAt(lastScheduledTime);
}
continue;
} else if (currStreamEvent.getType() != ComplexEvent.Type.CURRENT) {
continue;
}
long currentEventTime = (Long) timestampExpressionExecutor.execute(currStreamEvent);
if (lastCurrentEventTime < currentEventTime) {
lastCurrentEventTime = currentEventTime;
}
if (currentEventTime < endTime) {
cloneAppend(streamEventCloner, currStreamEvent);
} else {
if (flushed) {
appendToOutputChunk(streamEventCloner, complexEventChunks, lastCurrentEventTime, false);
flushed = false;
} else {
flushToOutputChunk(streamEventCloner, complexEventChunks, lastCurrentEventTime, false);
}
// update timestamp, call next processor
endTime = findEndTime(lastCurrentEventTime, startTime, timeToKeep);
cloneAppend(streamEventCloner, currStreamEvent);
// triggering the last batch expiration.
if (schedulerTimeout > 0) {
lastScheduledTime = siddhiAppContext.getTimestampGenerator().currentTime() + schedulerTimeout;
scheduler.notifyAt(lastScheduledTime);
}
}
}
}
for (ComplexEventChunk<StreamEvent> complexEventChunk : complexEventChunks) {
nextProcessor.process(complexEventChunk);
}
}
use of org.ballerinalang.siddhi.core.event.stream.StreamEvent in project ballerina by ballerina-lang.
the class ExternalTimeBatchWindowProcessor method cloneAppend.
private void cloneAppend(StreamEventCloner streamEventCloner, StreamEvent currStreamEvent) {
StreamEvent clonedStreamEvent = streamEventCloner.copyStreamEvent(currStreamEvent);
if (replaceTimestampWithBatchEndTime) {
clonedStreamEvent.setAttribute(endTime, timestampExpressionExecutor.getPosition());
}
currentEventChunk.add(clonedStreamEvent);
if (resetEvent == null) {
resetEvent = streamEventCloner.copyStreamEvent(currStreamEvent);
resetEvent.setType(ComplexEvent.Type.RESET);
}
}
use of org.ballerinalang.siddhi.core.event.stream.StreamEvent in project ballerina by ballerina-lang.
the class ExternalTimeBatchWindowProcessor method appendToOutputChunk.
private void appendToOutputChunk(StreamEventCloner streamEventCloner, List<ComplexEventChunk<StreamEvent>> complexEventChunks, long currentTime, boolean preserveCurrentEvents) {
ComplexEventChunk<StreamEvent> newEventChunk = new ComplexEventChunk<StreamEvent>(true);
ComplexEventChunk<StreamEvent> sentEventChunk = new ComplexEventChunk<StreamEvent>(true);
if (currentEventChunk.getFirst() != null) {
if (expiredEventChunk.getFirst() != null) {
// mark the timestamp for the expiredType event
expiredEventChunk.reset();
while (expiredEventChunk.hasNext()) {
StreamEvent expiredEvent = expiredEventChunk.next();
if (outputExpectsExpiredEvents) {
// add expired event to newEventChunk.
StreamEvent toExpireEvent = streamEventCloner.copyStreamEvent(expiredEvent);
toExpireEvent.setTimestamp(currentTime);
newEventChunk.add(toExpireEvent);
}
StreamEvent toSendEvent = streamEventCloner.copyStreamEvent(expiredEvent);
toSendEvent.setType(ComplexEvent.Type.CURRENT);
sentEventChunk.add(toSendEvent);
}
}
// add reset event in front of current events
StreamEvent toResetEvent = streamEventCloner.copyStreamEvent(resetEvent);
toResetEvent.setTimestamp(currentTime);
newEventChunk.add(toResetEvent);
// add old events
newEventChunk.add(sentEventChunk.getFirst());
// move to expired events
if (preserveCurrentEvents || storeExpiredEvents) {
currentEventChunk.reset();
while (currentEventChunk.hasNext()) {
StreamEvent currentEvent = currentEventChunk.next();
StreamEvent toExpireEvent = streamEventCloner.copyStreamEvent(currentEvent);
toExpireEvent.setType(StreamEvent.Type.EXPIRED);
expiredEventChunk.add(toExpireEvent);
}
}
// add current event chunk to next processor
newEventChunk.add(currentEventChunk.getFirst());
}
currentEventChunk.clear();
if (newEventChunk.getFirst() != null) {
complexEventChunks.add(newEventChunk);
}
}
use of org.ballerinalang.siddhi.core.event.stream.StreamEvent in project ballerina by ballerina-lang.
the class ExternalTimeWindowProcessor method process.
@Override
protected synchronized void process(ComplexEventChunk<StreamEvent> streamEventChunk, Processor nextProcessor, StreamEventCloner streamEventCloner) {
synchronized (this) {
while (streamEventChunk.hasNext()) {
StreamEvent streamEvent = streamEventChunk.next();
long currentTime = (Long) timeStampVariableExpressionExecutor.execute(streamEvent);
StreamEvent clonedEvent = streamEventCloner.copyStreamEvent(streamEvent);
clonedEvent.setType(StreamEvent.Type.EXPIRED);
// reset expiredEventChunk to make sure all of the expired events get removed,
// otherwise lastReturned.next will always return null and here while check is always false
expiredEventChunk.reset();
while (expiredEventChunk.hasNext()) {
StreamEvent expiredEvent = expiredEventChunk.next();
long expiredEventTime = (Long) timeStampVariableExpressionExecutor.execute(expiredEvent);
long timeDiff = expiredEventTime - currentTime + timeToKeep;
if (timeDiff <= 0) {
expiredEventChunk.remove();
expiredEvent.setTimestamp(currentTime);
streamEventChunk.insertBeforeCurrent(expiredEvent);
} else {
expiredEventChunk.reset();
break;
}
}
if (streamEvent.getType() == StreamEvent.Type.CURRENT) {
this.expiredEventChunk.add(clonedEvent);
}
expiredEventChunk.reset();
}
}
nextProcessor.process(streamEventChunk);
}
use of org.ballerinalang.siddhi.core.event.stream.StreamEvent in project ballerina by ballerina-lang.
the class FrequentWindowProcessor method process.
@Override
protected void process(ComplexEventChunk<StreamEvent> streamEventChunk, Processor nextProcessor, StreamEventCloner streamEventCloner) {
synchronized (this) {
StreamEvent streamEvent = streamEventChunk.getFirst();
streamEventChunk.clear();
long currentTime = siddhiAppContext.getTimestampGenerator().currentTime();
while (streamEvent != null) {
StreamEvent next = streamEvent.getNext();
streamEvent.setNext(null);
StreamEvent clonedEvent = streamEventCloner.copyStreamEvent(streamEvent);
clonedEvent.setType(StreamEvent.Type.EXPIRED);
String key = generateKey(streamEvent);
StreamEvent oldEvent = map.put(key, clonedEvent);
if (oldEvent != null) {
countMap.put(key, countMap.get(key) + 1);
streamEventChunk.add(streamEvent);
} else {
// This is a new event
if (map.size() > mostFrequentCount) {
List<String> keys = new ArrayList<String>(countMap.keySet());
for (int i = 0; i < mostFrequentCount; i++) {
int count = countMap.get(keys.get(i)) - 1;
if (count == 0) {
countMap.remove(keys.get(i));
StreamEvent expiredEvent = map.remove(keys.get(i));
expiredEvent.setTimestamp(currentTime);
streamEventChunk.add(expiredEvent);
} else {
countMap.put(keys.get(i), count);
}
}
// now we have tried to remove one for newly added item
if (map.size() > mostFrequentCount) {
// nothing happend by the attempt to remove one from the
// map so we are ignoring this event
map.remove(key);
// Here we do nothing just drop the message
} else {
// we got some space, event is already there in map object
// we just have to add it to the countMap
countMap.put(key, 1);
streamEventChunk.add(streamEvent);
}
} else {
countMap.put(generateKey(streamEvent), 1);
streamEventChunk.add(streamEvent);
}
}
streamEvent = next;
}
}
nextProcessor.process(streamEventChunk);
}
Aggregations