@Override public final void processWatermark(Watermark mark) throws Exception { List<Set<Context>> toTrigger = new ArrayList<>(); Iterator<Map.Entry<Long, Set<Context>>> it = watermarkTimers.entrySet().iterator(); while (it.hasNext()) { Map.Entry<Long, Set<Context>> triggers = it.next(); if (triggers.getKey() <= mark.getTimestamp()) { toTrigger.add(triggers.getValue()); it.remove(); } } for (Set<Context> ctxs : toTrigger) { for (Context ctx : ctxs) { // double check the time. it can happen that the trigger registers a new timer, // in that case the entry is left in the watermarkTimers set for performance reasons. // We have to check here whether the entry in the set still reflects the // currently set timer in the Context. if (ctx.watermarkTimer <= mark.getTimestamp()) { Trigger.TriggerResult triggerResult = ctx.onEventTime(ctx.watermarkTimer); processTriggerResult(triggerResult, ctx.key, ctx.window); } } } output.emitWatermark(mark); this.currentWatermark = mark.getTimestamp(); }
@Override public void processWatermark(Watermark mark) throws Exception { // if we receive a Long.MAX_VALUE watermark we forward it since it is used // to signal the end of input and to not block watermark progress downstream if (mark.getTimestamp() == Long.MAX_VALUE && mark.getTimestamp() > currentWatermark) { currentWatermark = Long.MAX_VALUE; output.emitWatermark(mark); } }
@Override public void processWatermark(Watermark mark) throws Exception { boolean fire; do { Timer<K, W> timer = watermarkTimersQueue.peek(); if (timer != null && timer.timestamp <= mark.getTimestamp()) { fire = true; watermarkTimers.remove(timer); watermarkTimersQueue.remove(); context.key = timer.key; context.window = timer.window; setKeyContext(timer.key); ListState<StreamRecord<IN>> windowState; MergingWindowSet<W> mergingWindows = null; if (windowAssigner instanceof MergingWindowAssigner) { mergingWindows = getMergingWindowSet(); W stateWindow = mergingWindows.getStateWindow(context.window); windowState = getPartitionedState(stateWindow, windowSerializer, windowStateDescriptor); } else { windowState = getPartitionedState(context.window, windowSerializer, windowStateDescriptor); } TriggerResult triggerResult = context.onEventTime(timer.timestamp); fireOrContinue(triggerResult, context.window, windowState); if (triggerResult.isPurge() || (windowAssigner.isEventTime() && isCleanupTime(timer.window, timer.timestamp))) { cleanup(timer.window, windowState, mergingWindows); } } else { fire = false; } } while (fire); output.emitWatermark(mark); this.currentWatermark = mark.getTimestamp(); }