Skip to content

[FLINK-39520] Preparatory refactoring for channel state recovery (no behavior change)#28651

Open
1996fanrui wants to merge 5 commits into
apache:masterfrom
1996fanrui:39520/pr
Open

[FLINK-39520] Preparatory refactoring for channel state recovery (no behavior change)#28651
1996fanrui wants to merge 5 commits into
apache:masterfrom
1996fanrui:39520/pr

Conversation

@1996fanrui

@1996fanrui 1996fanrui commented Jul 6, 2026

Copy link
Copy Markdown
Member

What is the purpose of the change

[FLINK-39520] Preparatory refactoring for channel state recovery (no behavior change).

It's part 1 of FLINK-38544 (checkpointing during recovery of unaligned checkpoint state). This PR only refactors code in preparation for the reworked channel-state recovery; it also carries one standalone [hotfix] commit fixing a busy-spin in the multiple-input processor.

Brief change log

  • [hotfix] Report END_OF_INPUT from multiple-input processor when all inputs finished
  • [FLINK-39520][network] Decouple LocalInputChannel recovery wiring from toBeConsumedBuffers
  • [FLINK-39520][checkpoint] Extract AbstractInputChannelRecoveredStateHandler with concrete no-filtering/filtering handlers
  • [FLINK-39520][network] Add InputGate#getChannel(InputChannelInfo)
  • [FLINK-39520][network] Additive logging overload; widen releaseAllResources visibility

Verifying this change

This change is a refactoring without behavior change; it is covered by existing tests (mechanical test adaptations only).

Does this pull request potentially affect one of the following parts:

  • Dependencies (does it add or upgrade a dependency): no
  • The public API, i.e., is any changed class annotated with @Public(Evolving): no
  • The serializers: no
  • The runtime per-record code paths (performance sensitive): no
  • Anything that affects deployment or recovery: JobManager (and its components), Checkpointing, Kubernetes/Yarn, ZooKeeper: no
  • The S3 file system connector: no

Documentation

  • Does this pull request introduce a new feature? no

@flinkbot

flinkbot commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

CI report:

Bot commands The @flinkbot bot supports the following commands:
  • @flinkbot run azure re-run the last Azure build

rkhachatryan and others added 5 commits July 6, 2026 13:52
…nputs finished

StreamMultipleInputProcessor.processInput returned NOTHING_AVAILABLE when no
input was selectable, even once all inputs were finished. Since
getAvailableFuture() returns AVAILABLE as soon as all inputs are finished, the
mailbox loop then never blocks and would spin on processInput at 100% CPU if it
were ever invoked again after the operator finished.

This is a latent inconsistency with single-input processors (which keep
returning END_OF_INPUT once finished) and is independent of any particular
feature; it is just not reached today because a task suspends on the first
END_OF_INPUT and processInput is not called again. The checkpointing-during-
recovery work (later in this series) does re-invoke processInput after an
operator finishes during recovery, which would otherwise turn this into a hang.

Report END_OF_INPUT when there is nothing to read and all inputs are finished,
consistent with single-input processors and
MultipleInputSelectionHandler#calculateOverallStatus.
…m toBeConsumedBuffers

Split the single toBeConsumedBuffers queue into two queues with disjoint
responsibilities:

  - recoveredBuffers (new): holds buffers migrated from RecoveredInputChannel
    during construction; consumed by getNextRecoveredBuffer() which retains
    the priority-event interleaving and last-buffer dynamic next-data-type
    detection introduced by FLINK-39018.
  - toBeConsumedBuffers (existing): reverted to its pre-FLINK-39018 role of
    holding FullyFilledBuffer partial-buffer splits only. The recovery-aware
    early branch in getNextBuffer() and the checkpointStarted inflight scan
    no longer touch this queue.

Restores the checkState(toBeConsumedBuffers.isEmpty()) guard in
requestSubpartitions() (removed by cebc174). hasPendingPriorityEvent,
notifyPriorityEvent, and the constructor signature are unchanged.

Pure refactor: no public API change, no new tests; verified by the 9 existing
LocalInputChannelTest regression cases.
…andler with concrete no-filtering/filtering handlers

Single-file class split of RecoveredChannelStateHandler.java; all classes stay
package-private in this file. No behavior change.

- New abstract AbstractInputChannelRecoveredStateHandler: fields inputGates,
  channelMapping, rescaledChannels, oldToNewMappings; methods getMappedChannels,
  calculateMapping, getChannel - verbatim extraction from
  InputChannelRecoveredStateHandler. Adds a closeInternal() template hook used
  by later phases.
- New NoSpillingHandler: recover() is the verbatim old non-filtering branch
  (onRecoveredStateBuffer(descriptor) followed by
  onRecoveredStateBuffer(buffer.retainBuffer()), same try/finally recycle);
  inherits the verbatim network-pool getBuffer.
- New FilteringHandler (the v1 filtering behavior, verbatim): recover() = old
  recoverWithFiltering (filteringHandler.filterAndRewrite(...,
  channel::requestBufferBlocking) delivering List<Buffer> via
  onRecoveredStateBuffer); getBuffer = old getPreFilterBuffer (reusable heap
  MemorySegment, preFilterBufferInUse invariant); closeInternal = old
  segment-freeing close.
- New static create(...) factory selecting NoSpillingHandler vs
  FilteringHandler - equivalent to the old internal if-branch.
  SequentialChannelStateReaderImpl switches from direct construction to the
  factory (mechanical).
- ResultSubpartitionRecoveredStateHandler: untouched.
- Trace label in RecoveredInputChannel.onRecoveredStateBuffer:
  "InputChannelRecoveredStateHandler#recover" -> "NoSpillingHandler#recover"
  (final label).
- Tests: mechanical adaptation of InputChannelRecoveredStateHandlerTest,
  RecoveredChannelStateHandlerTest.
- InputGate: new abstract InputChannel getChannel(InputChannelInfo).
- SingleInputGate: channels[channelInfo.getInputChannelIdx()]. UnionInputGate:
  resolve via inputGatesByGateIndex.get(channelInfo.getGateIdx())
  .getChannel(channelInfo) (correct global-vs-member index semantics).
  InputGateWithMetrics: delegate. CheckpointedInputGate: delegate helper.
- AbstractStreamTaskNetworkInput: getChannel(channelInfo.getInputChannelIdx())
  -> getChannel(channelInfo).
- Test impls: MockInputGate, MockIndexedInputGate,
  AlignedCheckpointsMassiveRandomTest's inner gate.
…ources visibility

- NetworkActionsLogger: additive tracePersist(String, Object, Object, long)
  overload; the existing Buffer overload delegates to it.
- RecoveredInputChannel#releaseAllResources: package-private -> public.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants