Martijn Visser created FLINK-40499:
--------------------------------------

             Summary: Final MAX_WATERMARK is dropped at drain when the source's 
last announced status is IDLE
                 Key: FLINK-40499
                 URL: https://issues.apache.org/jira/browse/FLINK-40499
             Project: Flink
          Issue Type: Bug
          Components: Runtime / Task
            Reporter: Martijn Visser


When a job drains (bounded input finishing, or stop-with-savepoint --drain),
{{StreamTask.endData}} calls {{advanceToEndOfEventTime()}}, which for source 
tasks emits
{{Watermark.MAX_WATERMARK}} directly into the operator chain output
({{SourceOperatorStreamTask.java:217-219}}; same in {{SourceStreamTask}} and
{{MultipleInputStreamTask}}). However, both 
{{RecordWriterOutput.emitWatermark}} and
{{ChainingOutput.emitWatermark}} silently drop any watermark while the last 
announced
{{WatermarkStatus}} is IDLE. A source subtask that is idle at drain time 
therefore never
delivers its final MAX watermark.

If at least one sibling channel is active at drain, its MAX_WATERMARK rescues 
downstream
(idle channels are excluded from the min). If *all* channels are idle — e.g. a 
bounded
Kafka topic whose partitions ran dry before the idle timeout, then the job 
finishes —
downstream completes with the watermark stuck at the last flushed value: 
event-time
timers and windows waiting for {{Long.MAX_VALUE}} never fire, and the final 
output is
silently missing.

Reproduction (both red on master):
* Task level: a {{SourceOperatorStreamTask}} (mock source whose reader calls
  {{output.markIdle()}} and then finishes) drains with task output
  {{[WatermarkStatus(IDLE), EndOfData(DRAIN)]}} — no MAX watermark — versus
  {{[MAX_WATERMARK, EndOfData(DRAIN)]}} in the existing green test
  {{testEmittingMaxWatermarkAfterReadingAllRecords}} for a non-idle source.
* Unit level: {{ChainingOutput}}: {{emitWatermarkStatus(IDLE)}} followed by
  {{emitWatermark(MAX_WATERMARK)}} — the MAX watermark is dropped at the idle 
guard
  ({{ChainingOutput.java:117-120}}; identical guard in 
{{RecordWriterOutput.java:149-152}}).

No rescue mechanism exists: {{advanceToEndOfEventTime}} emits MAX without a 
preceding
ACTIVE status; {{EndOfData}} / {{EndOfPartitionEvent}} do nothing 
watermark-related
downstream; and non-source tasks' {{advanceToEndOfEventTime}} is an explicit 
no-op.

Proposed fix: emit {{WatermarkStatus.ACTIVE}} before the MAX watermark in the
{{advanceToEndOfEventTime}} paths — the pattern already used by
{{TimestampsAndWatermarksOperator.WatermarkEmitter}} and the table
{{WatermarkAssignerOperator.processWatermark}}, and the same ordering rule 
FLINK-40475
applies inside {{StatusWatermarkValve}}. Longer term, a FINISHED watermark 
status
(FLINK-38477) would subsume this.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to