merlimat opened a new pull request, #26151:
URL: https://github.com/apache/pulsar/pull/26151

   ### Motivation
   
   Follow-up to #26131. The per-segment receive loops re-arm unconditionally 
into
   an unbounded `V5ReceiveQueue`, so if the application stalls, the buffer grows
   without bound: the v5 layer keeps draining the v4 consumers, which keep
   issuing flow permits to the broker. The v5 layer effectively defeats the v4
   consumer's `receiverQueueSize` flow control end-to-end.
   
   ### Modifications
   
   Restore backpressure, modelled on v4 `MultiTopicsConsumerImpl`'s pause/resume
   of sub-consumers:
   
   - `V5ReceiveQueue.offer()` now returns a `CompletableFuture<Void>` capacity
     signal. It completes immediately while the buffer has room; once the buffer
     reaches the high watermark (`receiverQueueSize`) the producer is parked
     until the consumer drains it to half. v4's fairness clause is carried over:
     once any producer is parked, further offers park at the low watermark too,
     so active segments can't hold the buffer above the resume threshold and
     starve parked peers.
   - A new `MessageSink` interface carries the capacity future across the
     single-topic/multi-topic sink boundary, so the shared mux's fullness pauses
     every per-topic segment loop.
   - Each per-segment receive/read loop re-arms only when the capacity future
     completes. A paused loop lets the underlying v4 consumer's receiver queue
     fill and stop issuing permits — backpressure reaches the broker.
   - Fast path: while the buffer is comfortably below the watermark, `offer()`
     grants capacity with a shared pre-completed future decided on the caller
     thread — the fast-consumer hot path pays no per-message allocation and no
     serialized executor hop. The size snapshot may lag by the offers still in
     flight, so the effective bound is `receiverQueueSize` + one message per
     producer.
   - Resume posts each capacity grant as its own executor task (as v4 does)
     rather than completing inline, so a wide release of parked segments doesn't
     stall queued user receive completions behind O(#segments) re-arm work.
   - `close()` releases parked producers so their loops observe the close.
   
   ### Verifying this change
   
   7 new `V5ReceiveQueue` unit tests: fast-path immediate grant, immediate
   completion below the watermark, parking at the high watermark and resume on
   drain, fairness parking of a second producer above the low watermark, resume
   through the `receiveMulti` and timed-receive drain paths, and `close()`
   releasing parked producers. Full `pulsar-client-v5` suite passes (96 tests).
   


-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to