Skip to content

feat: Add BidirectionalGracefulShutdown CancellationStrategy#3024

Draft
He-Pin wants to merge 1 commit into
mainfrom
feature/bidi-stream-closing-semantics
Draft

feat: Add BidirectionalGracefulShutdown CancellationStrategy#3024
He-Pin wants to merge 1 commit into
mainfrom
feature/bidi-stream-closing-semantics

Conversation

@He-Pin

@He-Pin He-Pin commented May 31, 2026

Copy link
Copy Markdown
Member

Motivation

Addresses issue #17997 - Clarify stream closing semantics for bidirectional components.

When a bidirectional component is about to finish, completing the downstream side (regularly or with an error) can race against cancelling the upstream side. If the cancellation arrives first, the error signal is lost because the connection is already cancelled.

Modification

  • Added new strategy to
  • This strategy first completes all output ports, then waits for a grace period to allow the error to propagate through the counterpart, and finally cancels all input ports
  • Added Java API method
  • Added comprehensive tests to verify the new behavior
  • The strategy prevents race conditions in BidiFlow stacks where error propagation is important

Result

Tests

  • stream-tests / Test / testOnly org.apache.pekko.stream.scaladsl.CancellationStrategySpec: All 15 tests passed

References

Motivation:
Addresses issue #17997 - Clarify stream closing semantics for bidirectional components.
When a bidirectional component is about to finish, completing the downstream side (regularly or with an error) can race against cancelling the upstream side. If the cancellation arrives first, the error signal is lost because the connection is already cancelled.

Modification:
- Added new  strategy to
- This strategy first completes all output ports, then waits for a grace period to allow the error to propagate through the counterpart, and finally cancels all input ports
- Added Java API  method
- Added comprehensive tests to verify the new behavior
- The strategy prevents race conditions in BidiFlow stacks where error propagation is important

Result:
- Bidirectional components can now gracefully shut down by completing outputs first
- Error signals have a chance to propagate through the counterpart before upstream cancellation
- Addresses the race condition described in akka/akka-core#17997

Tests:
- stream-tests / Test / testOnly org.apache.pekko.stream.scaladsl.CancellationStrategySpec: All 15 tests passed

Refs: akka/akka-core#17997
@He-Pin He-Pin marked this pull request as draft May 31, 2026 18:28
* through both inputs and outputs, and error propagation is important for proper diagnostics.
*
* @param delay the grace period to wait after completing outputs before cancelling inputs
*/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@since 2.0.0

* the error has a chance to bubble through the counterpart before the upstream is cancelled.
*
* @param delay the grace period to wait after completing outputs before cancelling inputs
*/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@since 2.0.0

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.

Clarify stream closing semantics for bidirectional components

2 participants