Skip to content

feat: add maxTotalBufferSize to MergeHub for aggregate queue bound - #3392

Open
He-Pin wants to merge 1 commit into
mainfrom
feat/mergehub-max-total-buffer-size
Open

feat: add maxTotalBufferSize to MergeHub for aggregate queue bound#3392
He-Pin wants to merge 1 commit into
mainfrom
feat/mergehub-max-total-buffer-size

Conversation

@He-Pin

@He-Pin He-Pin commented Jul 27, 2026

Copy link
Copy Markdown
Member

Motivation

MergeHub.source uses an unbounded AbstractNodeQueue as its central queue. While per-producer backpressure via perProducerBufferSize limits each individual producer's contribution, there is no aggregate bound across all producers. In dynamic scenarios where producers continuously materialize while downstream is stalled, the queue grows without limit, leading to OOM.

Fixes #3248

Modification

  • Add maxTotalBufferSize parameter to MergeHub (scaladsl + javadsl)
  • Track buffered element count with AtomicInteger (incremented on enqueue, decremented on consume)
  • New producers are cancelled at registration when the count meets or exceeds the threshold
  • Default 0 preserves existing unlimited behavior (fully backward compatible)

New API methods:

  • MergeHub.source[T](perProducerBufferSize, maxTotalBufferSize) (scaladsl)
  • MergeHub.sourceWithDraining[T](perProducerBufferSize, maxTotalBufferSize) (scaladsl)
  • MergeHub.of[T](clazz, perProducerBufferSize, maxTotalBufferSize) (javadsl)
  • MergeHub.withDraining[T](clazz, perProducerBufferSize, maxTotalBufferSize) (javadsl)

Result

Users can bound aggregate MergeHub queue growth via admission control, preventing OOM in dynamic producer churn scenarios. The bound is a soft admission threshold — transient overshoot up to the per-producer buffer of concurrently admitted producers is possible.

Tests

  • sbt "stream-tests / Test / testOnly org.apache.pekko.stream.scaladsl.HubSpec -- -z MergeHub" — 17 tests passed (including 2 new directional tests)
  • sbt "stream / mimaReportBinaryIssues" — passed (purely additive API)
  • scalafmt --mode diff-ref=origin/main — applied
  • sbt headerCreateAll — applied

References

Fixes #3248

Motivation:
MergeHub's central queue is unbounded. In dynamic producer scenarios
where producers continuously materialize while downstream is stalled,
the queue grows without limit leading to OOM (issue #3248).

Modification:
Add maxTotalBufferSize parameter to MergeHub (scaladsl + javadsl).
Track buffered element count with AtomicInteger. New producers are
cancelled at registration when the count meets or exceeds the threshold.
Default 0 preserves existing unlimited behavior.

Result:
Users can bound aggregate MergeHub queue growth via admission control,
preventing OOM in dynamic producer churn scenarios.

Tests:
- sbt "stream-tests / Test / testOnly org.apache.pekko.stream.scaladsl.HubSpec -- -z MergeHub"
  17 tests passed (including 2 new directional tests)
- sbt "stream / mimaReportBinaryIssues" passed

References:
Fixes #3248
* New producers are cancelled at registration when the buffered element count meets or exceeds this value.
* Transient overshoot up to the per-producer buffer of concurrently admitted producers is possible.
* Use 0 for unlimited (default behavior).
*/

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

* New producers are cancelled at registration when the buffered element count meets or exceeds this value.
* Transient overshoot up to the per-producer buffer of concurrently admitted producers is possible.
* Use 0 for unlimited (default behavior).
*/

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

* New producers are cancelled at registration when the buffered element count meets or exceeds this value.
* Transient overshoot up to the per-producer buffer of concurrently admitted producers is possible.
* Use 0 for unlimited (default behavior).
*/

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.

this class also needs @since 2.0.0 on the new public methods

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.

MergeHub central queue unbounded in dynamic producer scenarios

2 participants