Producer-synchronous, consumer-asynchronous bridge between a provider and a subscriber's stream.
Two shapes, because two kinds of stream want opposite things on overflow:
DeltaMailbox — FIFO for state-mutating events. Silent drops are never acceptable: a missed Spent corrupts the subscriber's view permanently and invisibly. A bounded buffer that fills therefore fails the subscription rather than dropping.
LatestValueMailbox — size-1, newer wins, for single-source-of-truth cells (tip, params, transaction status). Here dropping intermediate values is precisely correct.
Not public API: this is one implementation of ScalusAsyncSource, and adapters are written against that interface so the buffering strategy stays free to change.
offer is buffer-then-deliver, and a producer that needs several events to land atomically relative to its own state can split the two: offerBuffered under its lock, flush after releasing it. That is what lets the hub register a subscription and enqueue its seed as one indivisible step without ever running a consumer's continuation while holding the hub monitor.
Nothing observable escapes during the buffered phase — no promise is completed, no onCancel hook runs. Both are deferred to flush.
Every way a mailbox can die — explicit cancel, clean close, producer fail, or a bounded buffer overflowing — fires onCancel exactly once. A subscription that ends by any route must stop costing the provider work; the alternative is a dead subscription matched against every block for the lifetime of the process.
Deliver whatever offerBuffered left pending: complete a waiting pull, and fire onCancel if the mailbox died while buffering. Idempotent and cheap when there is nothing to do.
Deliver whatever offerBuffered left pending: complete a waiting pull, and fire onCancel if the mailbox died while buffering. Idempotent and cheap when there is nothing to do.
Pull with nothing to cancel on. Convenient for synchronous callers and tests; anything that may need to interrupt a parked wait should pass a real token.
Pull with nothing to cancel on. Convenient for synchronous callers and tests; anything that may need to interrupt a parked wait should pass a real token.
The token is how a Future-returning API becomes abortable at all. Future has no cancellation of its own, so an effect system that needs to interrupt a parked pull — an fs2 .timeout, a cancelled Resource.use, a runtime shutting down — has nothing to pull the plug on unless the capability is passed in. Adapters bridge their own cancellation onto this token; without it they can only mask cancellation and hang.
Cancelling a pull does not end the subscription: the next pull starts a fresh wait. cancel is what ends the subscription.
Single-consumer: exactly one caller pulls at a time, per source. Pulling again while a pull is outstanding returns the same future — so cancelling one cancels both.