This is an automated email from the ASF dual-hosted git repository.
1996fanrui pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/flink.git
The following commit(s) were added to refs/heads/master by this push:
new 3e1c65ec36a [FLINK-40519][network] Deliver priority barrier to a
credited remote reader while the subpartition is blocked during recovery
3e1c65ec36a is described below
commit 3e1c65ec36aa7725427b39b9affa5709a1f05b5b
Author: Rui Fan <[email protected]>
AuthorDate: Mon Aug 31 17:34:53 2026 +0200
[FLINK-40519][network] Deliver priority barrier to a credited remote reader
while the subpartition is blocked during recovery
---
.../network/partition/PipelinedSubpartition.java | 15 ++++++++--
.../partition/PipelinedSubpartitionTest.java | 34 ++++++++++++++++++++++
2 files changed, 46 insertions(+), 3 deletions(-)
diff --git
a/flink-runtime/src/main/java/org/apache/flink/runtime/io/network/partition/PipelinedSubpartition.java
b/flink-runtime/src/main/java/org/apache/flink/runtime/io/network/partition/PipelinedSubpartition.java
index 2e4b674a3a3..e5369d78506 100644
---
a/flink-runtime/src/main/java/org/apache/flink/runtime/io/network/partition/PipelinedSubpartition.java
+++
b/flink-runtime/src/main/java/org/apache/flink/runtime/io/network/partition/PipelinedSubpartition.java
@@ -472,7 +472,7 @@ public class PipelinedSubpartition extends
ResultSubpartition implements Channel
// When blocked (e.g. by RECOVERY_COMPLETION event), only allow
priority buffers
// (e.g. unaligned checkpoint barriers) to be polled. Regular
buffers remain blocked
// until resumeConsumption() is called. See
needNotifyPriorityEvent() for details.
- if (isBlocked && buffers.getNumPriorityElements() == 0) {
+ if (isBlockedForDelivery()) {
return null;
}
@@ -619,11 +619,20 @@ public class PipelinedSubpartition extends
ResultSubpartition implements Channel
}
}
+ /**
+ * Blocked for delivery when blocked (e.g. by RECOVERY_COMPLETION) with no
priority element
+ * queued; priority buffers (e.g. unaligned barriers) are still delivered
while blocked.
+ */
+ @GuardedBy("buffers")
+ private boolean isBlockedForDelivery() {
+ return isBlocked && buffers.getNumPriorityElements() == 0;
+ }
+
@GuardedBy("buffers")
private boolean isDataAvailableUnsafe() {
assert Thread.holdsLock(buffers);
- return !isBlocked && (flushRequested || getNumberOfFinishedBuffers() >
0);
+ return !isBlockedForDelivery() && (flushRequested ||
getNumberOfFinishedBuffers() > 0);
}
private Buffer.DataType getNextBufferTypeUnsafe() {
@@ -751,7 +760,7 @@ public class PipelinedSubpartition extends
ResultSubpartition implements Channel
@SuppressWarnings("FieldAccessNotGuarded")
@Override
public int getBuffersInBacklogUnsafe() {
- if (isBlocked || buffers.isEmpty()) {
+ if (isBlockedForDelivery() || buffers.isEmpty()) {
return 0;
}
diff --git
a/flink-runtime/src/test/java/org/apache/flink/runtime/io/network/partition/PipelinedSubpartitionTest.java
b/flink-runtime/src/test/java/org/apache/flink/runtime/io/network/partition/PipelinedSubpartitionTest.java
index 2e8e34d4001..71bc5c200e4 100644
---
a/flink-runtime/src/test/java/org/apache/flink/runtime/io/network/partition/PipelinedSubpartitionTest.java
+++
b/flink-runtime/src/test/java/org/apache/flink/runtime/io/network/partition/PipelinedSubpartitionTest.java
@@ -30,6 +30,7 @@ import
org.apache.flink.runtime.io.network.api.serialization.EventSerializer;
import org.apache.flink.runtime.io.network.buffer.Buffer;
import org.apache.flink.runtime.io.network.buffer.BufferBuilderTestUtils;
import org.apache.flink.runtime.io.network.buffer.BufferConsumer;
+import
org.apache.flink.runtime.io.network.partition.consumer.EndOfOutputChannelStateEvent;
import org.apache.flink.runtime.io.network.util.TestConsumerCallback;
import org.apache.flink.runtime.io.network.util.TestProducerSource;
import org.apache.flink.runtime.io.network.util.TestSubpartitionConsumer;
@@ -472,6 +473,39 @@ public class PipelinedSubpartitionTest extends
SubpartitionTestBase {
.isInstanceOf(ExecutionException.class);
}
+ @TestTemplate
+ void testPriorityBarrierAvailableToCreditedReaderWhileBlocked() throws
Exception {
+ PipelinedSubpartition subpartition = createSubpartition();
+ subpartition.setChannelStateWriter(ChannelStateWriter.NO_OP);
+
+ // Block the subpartition, mirroring the RECOVERY_COMPLETION event
emitted during recovery.
+ subpartition.add(
+
EventSerializer.toBufferConsumer(EndOfOutputChannelStateEvent.INSTANCE, false));
+ pollBufferAndCheckType(subpartition,
Buffer.DataType.RECOVERY_COMPLETION);
+
+ // While blocked and without any priority element, a credited reader
sees no data.
+
assertThat(subpartition.getAvailabilityAndBacklog(true).isAvailable()).isFalse();
+ assertThat(subpartition.pollBuffer()).isNull();
+
+ // Enqueue an unaligned checkpoint barrier as a priority element.
+ CheckpointOptions options =
+ CheckpointOptions.unaligned(
+ CheckpointType.CHECKPOINT,
CheckpointStorageLocationReference.getDefault());
+ subpartition.add(
+ EventSerializer.toBufferConsumer(
+ new CheckpointBarrier(1L, System.currentTimeMillis(),
options), true));
+
+ // The credited-reader availability check must now report available so
the remote reader is
+ // enqueued and the priority barrier is delivered even though the
subpartition
+ // stays blocked.
+
assertThat(subpartition.getAvailabilityAndBacklog(true).isAvailable()).isTrue();
+ pollBufferAndCheckType(subpartition,
Buffer.DataType.PRIORITIZED_EVENT_BUFFER);
+
+ // After the priority element is consumed, the subpartition should
immediately re-block.
+
assertThat(subpartition.getAvailabilityAndBacklog(true).isAvailable()).isFalse();
+ assertThat(subpartition.pollBuffer()).isNull();
+ }
+
private BufferConsumer getTimeoutableBarrierBuffer(long checkpointId)
throws IOException {
CheckpointOptions checkpointOptions =
CheckpointOptions.alignedWithTimeout(