/** Advance the watermark to the specified time, firing any timers that should fire. */ public void advanceWatermark(Instant newWatermark) throws Exception { Preconditions.checkState( !newWatermark.isBefore(watermark), "Cannot move watermark time backwards from %s to %s", watermark.getMillis(), newWatermark.getMillis()); logInteraction("Advancing watermark to %d", newWatermark.getMillis()); watermark = newWatermark; timerInternals.advanceWatermark(runner, newWatermark); }
/** Advance the processing time to the specified time, firing any timers that should fire. */ public void advanceProcessingTime(Instant newProcessingTime) throws Exception { Preconditions.checkState( !newProcessingTime.isBefore(processingTime), "Cannot move processing time backwards from %s to %s", processingTime.getMillis(), newProcessingTime.getMillis()); logInteraction("Advancing processing time to %d", newProcessingTime.getMillis()); processingTime = newProcessingTime; timerInternals.advanceProcessingTime(runner, newProcessingTime); }
public Instant minimumWatermarkHold() { Instant minimum = null; for (State storage : inMemoryState.values()) { if (storage instanceof WatermarkStateInternal) { Instant hold = ((WatermarkStateInternal) storage).get().read(); if (minimum == null || (hold != null && hold.isBefore(minimum))) { minimum = hold; } } } return minimum; }
protected void checkTimestamp(WindowedValue<IN> ref, Instant timestamp) { if (timestamp.isBefore(ref.getTimestamp().minus(doFn.getAllowedTimestampSkew()))) { throw new IllegalArgumentException( String.format( "Cannot output with timestamp %s. Output timestamps must be no earlier than the " + "timestamp of the current input (%s) minus the allowed skew (%s). See the " + "DoFn#getAllowedTimestmapSkew() Javadoc for details on changing the allowed skew.", timestamp, ref.getTimestamp(), PeriodFormat.getDefault().print(doFn.getAllowedTimestampSkew().toPeriod()))); } }
private <W> PaneInfo describePane( Object key, Instant windowMaxTimestamp, PaneInfo previousPane, boolean isFinal) { boolean isFirst = previousPane == null; Timing previousTiming = isFirst ? null : previousPane.getTiming(); long index = isFirst ? 0 : previousPane.getIndex() + 1; long nonSpeculativeIndex = isFirst ? 0 : previousPane.getNonSpeculativeIndex() + 1; Instant outputWM = timerInternals.currentOutputWatermarkTime(); Instant inputWM = timerInternals.currentInputWatermarkTime(); // True if it is not possible to assign the element representing this pane a timestamp // which will make an ON_TIME pane for any following computation. // Ie true if the element's latest possible timestamp is before the current output watermark. boolean isLateForOutput = outputWM != null && windowMaxTimestamp.isBefore(outputWM); // True if all emitted panes (if any) were EARLY panes. // Once the ON_TIME pane has fired, all following panes must be considered LATE even // if the output watermark is behind the end of the window. boolean onlyEarlyPanesSoFar = previousTiming == null || previousTiming == Timing.EARLY; // True is the input watermark hasn't passed the window's max timestamp. boolean isEarlyForInput = !inputWM.isAfter(windowMaxTimestamp); Timing timing; if (isLateForOutput || !onlyEarlyPanesSoFar) { // The output watermark has already passed the end of this window, or we have already // emitted a non-EARLY pane. Irrespective of how this pane was triggered we must // consider this pane LATE. timing = Timing.LATE; } else if (isEarlyForInput) { // This is an EARLY firing. timing = Timing.EARLY; nonSpeculativeIndex = -1; } else { // This is the unique ON_TIME firing for the window. timing = Timing.ON_TIME; } WindowTracing.debug( "describePane: {} pane (prev was {}) for key:{}; windowMaxTimestamp:{}; " + "inputWatermark:{}; outputWatermark:{}; isLateForOutput:{}", timing, previousTiming, key, windowMaxTimestamp, inputWM, outputWM, isLateForOutput); if (previousPane != null) { // Timing transitions should follow EARLY* ON_TIME? LATE* switch (previousTiming) { case EARLY: checkState( timing == Timing.EARLY || timing == Timing.ON_TIME || timing == Timing.LATE, "EARLY cannot transition to %s", timing); break; case ON_TIME: checkState(timing == Timing.LATE, "ON_TIME cannot transition to %s", timing); break; case LATE: checkState(timing == Timing.LATE, "LATE cannot transtion to %s", timing); break; case UNKNOWN: break; } checkState(!previousPane.isLast(), "Last pane was not last after all."); } return PaneInfo.createPane(isFirst, isFinal, timing, index, nonSpeculativeIndex); }