You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@beam.apache.org by "CarloMariaProietti (via GitHub)" <gi...@apache.org> on 2026/09/17 08:23:13 UTC

[PR] Flink dropping watermarks fix [beam]

CarloMariaProietti opened a new pull request, #40149:
URL: https://github.com/apache/beam/pull/40149

   **Please** add a meaningful description for your change here
   ------------------------
   Fixes #39991
   
   Problem:
   The BufferingDoFnRunner class has the following issue: the minBufferedElementTimestamp field is intended to hold the minimum timestamp among all elements in currentBufferingElementsHandler. This semantic contract can be observed in the processElement and onTimer methods. However, checkpointCompleted violates this contract by setting minBufferedElementTimestamp to Long.MAX_VALUE without guaranteeing that currentBufferingElementsHandler is completely empty (while likely, it is not guaranteed; see #39991 for details).
   
   Solution:
   checkpointCompleted now sets minBufferedElementTimestamp to Long.MAX_VALUE only if currentBufferingElementsHandler is empty; otherwise, it recomputes the minimum timestamp according to its semantic invariant.
   
   Implementation Details:
   Implemented following the GRASP Polymorphism pattern. The semantics across implementations of the polymorphic getTimestamp method remain consistent with processElement and onTimer.
   
   Thank you for your contribution! Follow this checklist to help us incorporate your contribution quickly and easily:
   
    - [ ] Mention the appropriate issue in your description (for example: `addresses #123`), if applicable. This will automatically add a link to the pull request in the issue. If you would like the issue to automatically close on merging the pull request, comment `fixes #<ISSUE NUMBER>` instead.
    - [ ] Update `CHANGES.md` with noteworthy changes.
    - [ ] If this contribution is large, please file an Apache [Individual Contributor License Agreement](https://www.apache.org/licenses/icla.pdf).
   
   See the [Contributor Guide](https://beam.apache.org/contribute) for more tips on [how to make review process smoother](https://github.com/apache/beam/blob/master/CONTRIBUTING.md#make-the-reviewers-job-easier).
   
   To check the build health, please visit [https://github.com/apache/beam/blob/master/.test-infra/BUILD_STATUS.md](https://github.com/apache/beam/blob/master/.test-infra/BUILD_STATUS.md)
   
   GitHub Actions Tests Status (on master branch)
   ------------------------------------------------------------------------------------------------
   [![Build python source distribution and wheels](https://github.com/apache/beam/actions/workflows/build_wheels.yml/badge.svg?event=schedule&&?branch=master)](https://github.com/apache/beam/actions?query=workflow%3A%22Build+python+source+distribution+and+wheels%22+branch%3Amaster+event%3Aschedule)
   [![Python tests](https://github.com/apache/beam/actions/workflows/python_tests.yml/badge.svg?event=schedule&&?branch=master)](https://github.com/apache/beam/actions?query=workflow%3A%22Python+Tests%22+branch%3Amaster+event%3Aschedule)
   [![Java tests](https://github.com/apache/beam/actions/workflows/java_tests.yml/badge.svg?event=schedule&&?branch=master)](https://github.com/apache/beam/actions?query=workflow%3A%22Java+Tests%22+branch%3Amaster+event%3Aschedule)
   [![Go tests](https://github.com/apache/beam/actions/workflows/go_tests.yml/badge.svg?event=schedule&&?branch=master)](https://github.com/apache/beam/actions?query=workflow%3A%22Go+tests%22+branch%3Amaster+event%3Aschedule)
   
   See [CI.md](https://github.com/apache/beam/blob/master/CI.md) for more information about GitHub Actions CI or the [workflows README](https://github.com/apache/beam/blob/master/.github/workflows/README.md) to see a list of phrases to trigger workflows.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Flink dropping watermarks fix [beam]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #40149:
URL: https://github.com/apache/beam/pull/40149#issuecomment-5713422359

   Assigning reviewers:
   
   R: @jrmccluskey added as fallback since no labels match configuration
   
   
   Note: If you would like to opt out of this review, comment `assign to next reviewer`.
   
   Available commands:
   - `stop reviewer notifications` - opt out of the automated review tooling
   - `remind me after tests pass` - tag the comment author after tests pass
   - `waiting on author` - shift the attention set back to the author (any comment or push by the author will return the attention set to the reviewers)
   
   The PR bot will only process comments in the main thread (not review comments).


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Flink dropping watermarks hold fix [beam]

Posted by "jrmccluskey (via GitHub)" <gi...@apache.org>.
jrmccluskey commented on PR #40149:
URL: https://github.com/apache/beam/pull/40149#issuecomment-5715831390

   R: @bvolpato 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Flink dropping watermarks hold fix [beam]

Posted by "damccorm (via GitHub)" <gi...@apache.org>.
damccorm merged PR #40149:
URL: https://github.com/apache/beam/pull/40149


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Flink dropping watermarks hold fix [beam]

Posted by "damccorm (via GitHub)" <gi...@apache.org>.
damccorm commented on code in PR #40149:
URL: https://github.com/apache/beam/pull/40149#discussion_r4209071008


##########
runners/flink/src/main/java/org/apache/beam/runners/flink/translation/wrappers/streaming/stableinput/BufferingDoFnRunner.java:
##########
@@ -299,7 +299,12 @@ public void checkpointCompleted(long checkpointId) throws Exception {
         bufferingElementsHandler.clear();
       }
     }
-    minBufferedElementTimestamp = Long.MAX_VALUE;
+    minBufferedElementTimestamp =
+        currentBufferingElementsHandler
+            .getElements()
+            .mapToLong(e -> e.getTimestamp().getMillis())
+            .min()
+            .orElse(Long.MAX_VALUE);

Review Comment:
   A few thoughts on how `minBufferedElementTimestamp` is recomputed here:
   
   1. **Concurrent checkpoints (`maxConcurrentCheckpoints > 1`):** If checkpoint `N` completes while checkpoint `N+1` has already been snapshotted (and is still pending in `notYetAcknowledgedSnapshots`), `currentBufferingElementsHandler` has already rotated to the buffer for `N+2`. Only checking `currentBufferingElementsHandler` will miss elements still buffered in unacknowledged checkpoint `N+1` and can drop their watermark hold.
   2. **Locking (`Locker`):** When using `KeyedBufferingElementsHandler` (e.g., in `ExecutableStageDoFnOperator`), `getElements()` iterates keys and calls `backend.setCurrentKey(key)` / `state.get()` on the `KeyedStateBackend`. All other accesses to `BufferingElementsHandler` in this class are guarded by `try (Locker lock = locker != null ? locker.get() : null)`.
   3. **Avoiding extra state reads/deserialization:** Calling `currentBufferingElementsHandler.getElements()` on every `checkpointCompleted` forces Flink to read and deserialize all buffered elements in the active buffer (and scan all keys in RocksDB when keyed), only to read and deserialize them again when the next checkpoint completes.
   
   Could we instead track the minimum timestamp per buffer index in memory (e.g., a `long[] minTimestampPerBuffer` of size `numCheckpointBuffers` initialized to `Long.MAX_VALUE`)?
   - In `processElement` / `onTimer`, update `minTimestampPerBuffer[currentStateIndex]` (and `minBufferedElementTimestamp`).
   - In `checkpointCompleted`, reset `minTimestampPerBuffer[toBeAcked.internalId] = Long.MAX_VALUE` as each buffer is cleared, and then set `minBufferedElementTimestamp` to the min across `minTimestampPerBuffer`.
   
   That would avoid scanning/deserializing Flink state in `checkpointCompleted`, avoid the `Locker` issue, and naturally preserve watermark holds across multiple concurrent checkpoints. (If we also want holds preserved across job restarts, we could populate `minTimestampPerBuffer` from `pendingSnapshots` once in `initializeState`.)



##########
runners/flink/src/test/java/org/apache/beam/runners/flink/translation/wrappers/streaming/DoFnOperatorTest.java:
##########
@@ -2233,6 +2234,87 @@ public void finishBundle(FinishBundleContext context) {
             WindowedValues.valueInGlobalWindow(KV.of("key3", "finishBundle"))));
   }
 
+  /** Ensures that output watermark does not pass buffered elements */
+  @Test
+  public void testExactlyOnceBufferingOutputWatermarkCorrectness() throws Exception {
+    FlinkPipelineOptions options = FlinkPipelineOptions.defaults();
+    options.setStreaming(true);
+    options.setMaxBundleSize(1L);
+    options.setCheckpointingInterval(1L);
+    options.setCheckpointingMode("EXACTLY_ONCE");
+    options.setNumConcurrentCheckpoints(1);
+
+    TupleTag<String> outputTag = new TupleTag<>("main-output");
+
+    WindowedValues.FullWindowedValueCoder<String> windowedValueCoder =
+        WindowedValues.getFullCoder(StringUtf8Coder.of(), GlobalWindow.Coder.INSTANCE);
+
+    DoFn<String, String> doFn =
+        new DoFn<String, String>() {
+          @ProcessElement
+          // Use RequiresStableInput to force buffering elements
+          @RequiresStableInput
+          public void processElement(ProcessContext context) {
+            context.output(context.element());
+          }
+        };
+
+    DoFnOperator.MultiOutputOutputManagerFactory<String> outputManagerFactory =
+        new DoFnOperator.MultiOutputOutputManagerFactory<>(
+            outputTag,
+            WindowedValues.getFullCoder(StringUtf8Coder.of(), GlobalWindow.Coder.INSTANCE),
+            new SerializablePipelineOptions(options));
+
+    Supplier<DoFnOperator<String, String, String>> doFnOperatorSupplier =
+        () ->
+            new DoFnOperator<>(
+                doFn,
+                "stepName",
+                windowedValueCoder,
+                Collections.emptyMap(),
+                outputTag,
+                Collections.emptyList(),
+                outputManagerFactory,
+                WindowingStrategy.globalDefault(),
+                new HashMap<>(), /* side-input mapping */
+                Collections.emptyList(), /* side inputs */
+                options,
+                null,
+                null,
+                DoFnSchemaInformation.create(),
+                Collections.emptyMap());
+
+    DoFnOperator<String, String, String> doFnOperator = doFnOperatorSupplier.get();
+    OneInputStreamOperatorTestHarness<WindowedValue<String>, WindowedValue<String>> testHarness =
+        new OneInputStreamOperatorTestHarness<>(doFnOperator);
+
+    testHarness.open();
+
+    testHarness.processElement(
+        new StreamRecord<>(WindowedValues.timestampedValueInGlobalWindow("A", new Instant(10))));
+    testHarness.snapshot(1L, 0L);
+    testHarness.processElement(
+        new StreamRecord<>(WindowedValues.timestampedValueInGlobalWindow("B", new Instant(20))));
+    testHarness.processWatermark(new Watermark(100));
+    assertThat(
+        "A@10 has not yet completed the checkpoint; output watermark must be held at 10 until checkpoint completion",
+        doFnOperator.getCurrentOutputWatermark(),
+        is(10L));
+
+    doFnOperator.notifyCheckpointComplete(1L);
+    assertThat(
+        "A@10 has been checked but B@20 is still buffered; output watermark must not pass it",
+        doFnOperator.getCurrentOutputWatermark(),
+        is(20L));
+
+    testHarness.snapshot(2L, 0L);
+    doFnOperator.notifyCheckpointComplete(2L);
+    assertThat(
+        "B@20 has been checked and the buffer is empty; output watermark must advance to input watermark",
+        doFnOperator.getCurrentOutputWatermark(),
+        is(100L));
+  }

Review Comment:
   Nit: Since this test doesn't restore from a snapshot, `doFnOperatorSupplier` can be inlined to construct `doFnOperator` directly, and we should call `testHarness.close()` at the end (or use try-with-resources). Also might be nice to assert on `testHarness.getOutput()` at the end to verify that `A@10` and `B@20` were emitted in order before watermark `100`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Flink dropping watermarks hold fix [beam]

Posted by "damccorm (via GitHub)" <gi...@apache.org>.
damccorm commented on PR #40149:
URL: https://github.com/apache/beam/pull/40149#issuecomment-6087595170

   Making sure workflows succeed before proceeding


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Flink dropping watermarks hold fix [beam]

Posted by "codecov[bot] (via GitHub)" <gi...@apache.org>.
codecov[bot] commented on PR #40149:
URL: https://github.com/apache/beam/pull/40149#issuecomment-6088569484

   ## [Codecov](https://app.codecov.io/gh/apache/beam/pull/40149?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) Report
   :x: Patch coverage is `71.42857%` with `4 lines` in your changes missing coverage. Please review.
   :white_check_mark: Project coverage is 58.73%. Comparing base ([`76f6e6d`](https://app.codecov.io/gh/apache/beam/commit/76f6e6d7c0c1b2ce582c73d068ad9260cf15c5f3?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)) to head ([`d96cc98`](https://app.codecov.io/gh/apache/beam/commit/d96cc984b4529fe0cb3b439b262a63dbf54c0e39?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache)).
   :warning: Report is 110 commits behind head on master.
   
   | [Files with missing lines](https://app.codecov.io/gh/apache/beam/pull/40149?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Patch % | Lines |
   |---|---|---|
   | [...ers/streaming/stableinput/BufferingDoFnRunner.java](https://app.codecov.io/gh/apache/beam/pull/40149?src=pr&el=tree&filepath=runners%2Fflink%2Fsrc%2Fmain%2Fjava%2Forg%2Fapache%2Fbeam%2Frunners%2Fflink%2Ftranslation%2Fwrappers%2Fstreaming%2Fstableinput%2FBufferingDoFnRunner.java&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#diff-cnVubmVycy9mbGluay9zcmMvbWFpbi9qYXZhL29yZy9hcGFjaGUvYmVhbS9ydW5uZXJzL2ZsaW5rL3RyYW5zbGF0aW9uL3dyYXBwZXJzL3N0cmVhbWluZy9zdGFibGVpbnB1dC9CdWZmZXJpbmdEb0ZuUnVubmVyLmphdmE=) | 71.42% | [4 Missing :warning: ](https://app.codecov.io/gh/apache/beam/pull/40149?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) |
   
   <details><summary>Additional details and impacted files</summary>
   
   
   
   ```diff
   @@             Coverage Diff              @@
   ##             master   #40149      +/-   ##
   ============================================
   + Coverage     56.16%   58.73%   +2.56%     
   - Complexity     2288    13919   +11631     
   ============================================
     Files          1124     2585    +1461     
     Lines        178336   271702   +93366     
     Branches       1489    11243    +9754     
   ============================================
   + Hits         100170   159593   +59423     
   - Misses        75645   106107   +30462     
   - Partials       2521     6002    +3481     
   ```
   
   | [Flag](https://app.codecov.io/gh/apache/beam/pull/40149/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | Coverage Δ | |
   |---|---|---|
   | [java](https://app.codecov.io/gh/apache/beam/pull/40149/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache) | `65.27% <71.42%> (-10.52%)` | :arrow_down: |
   
   Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache#carryforward-flags-in-the-pull-request-comment) to find out more.
   </details>
   
   [:umbrella: View full report in Codecov by Harness](https://app.codecov.io/gh/apache/beam/pull/40149?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).   
   :loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=apache).
   <details><summary> :rocket: New features to boost your workflow: </summary>
   
   - :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
   - :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
   </details>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Flink dropping watermarks hold fix [beam]

Posted by "CarloMariaProietti (via GitHub)" <gi...@apache.org>.
CarloMariaProietti commented on PR #40149:
URL: https://github.com/apache/beam/pull/40149#issuecomment-6064748794

   @jrmccluskey Thank you for reviewing! I've fixed the logic in DoFnOperator so that the minimum timestamp is tracked per checkpoint buffer and extended the test to cover your point. Please let me know whether watermark holds should be preserved across job restarts.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Flink dropping watermarks hold fix [beam]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #40149:
URL: https://github.com/apache/beam/pull/40149#issuecomment-5715843723

   Stopping reviewer notifications for this pull request: review requested by someone other than the bot, ceding control. If you'd like to restart, comment `assign set of reviewers`


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: github-unsubscribe@beam.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org