Class UpstreamBalancer

java.lang.Object
io.micronaut.http.body.stream.UpstreamBalancer

@Internal public final class UpstreamBalancer extends Object
This class merges the backpressure of two data streams. The bytes signaled to the upstream is always the minimum of the consumed bytes of the two downstreams.

Implementation notes: This is a bit tricky to implement without locking due to the concurrent nature of BufferConsumer.Upstream. Let l and r be the total bytes consumed by the left and right downstreams respectively. We have signalled already the consumption of min(l, r) bytes upstream. The AtomicLong stores the difference l-r. Now, assume the left downstream (wlog) signals consumption of n further bytes. There are three cases:

  • l>r, thus l-r>0: right downstream is already lagging behind, don't send any demand upstream
  • l<r, and l+n<r: left downstream stays lagging behind, send the full n demand upstream
  • l<r, but l+n>r: left downstream was lagging behind but now right downstream is. Just send r-l=abs(l-r) upstream

The last two cases can be combined into sending min(n, abs(l-r)) upstream. So we only need to test for the first case.