Motivation
I'm going to factor out the async runtime code in foyer (cc @MrCroxx) to make madsim an opt-outable feature.
Typically, it would be like a runtime module to hide the implementation.
Before that, I noticed foyer uses several tokio::sync primitives which can be replaced with mea:
tokio::sync::Barrier can be mea::barrier::Barrier
tokio::sync::oneshot can be mea::oneshot
tokio::sync::Mutex can be mea::mutex::Mutex
tokio::sync::broadcast is lacking
Thus, I think we can support the broadcast channel in mea to replace all tokio::sync usage in foyer.
Design and Implementation
The most common design is to use a circular queue, where senders put elements at the end, and each receiver tracks its current position and consumes new elements if any are available.
Some decision points:
- What if a receiver lags too much until the next new elements put would overflow its current position?
tokio's broadcast would trigger a Lagged error and forward the receiver's position to the oldest value contained by the channel.
async-broadcast supports different overflow policy: (1) like what tokio's broadcast does, (2) sender waits for all the receivers to move forward.
- Then we need to decide the API structure, like:
- How to make a broadcast channel?
- How to make a new sender/receiver of the broadcast channel?
- How sender's/receiver's (try) send/recv signatures look like, esp. sync/async. faillible, etc.
- How to bridge Rust's
Future & Waker mechanism?
Typically, each receiver would consume elements until there are no more and register a waker on that cell. Once a sender puts a new element in that cell, it can wake up all the wakers so that receivers can consume the new elements.
The main point here is how we can efficiently mutate the shared circular queue and reduce lock usage as much as possible.
Besides, if we allow sender to wait on channel full, we may need to register wakers for wating senders.
Reference
cc @BewareMyPower @orthur2
Motivation
I'm going to factor out the async runtime code in foyer (cc @MrCroxx) to make
madsiman opt-outable feature.Typically, it would be like a runtime module to hide the implementation.
Before that, I noticed foyer uses several
tokio::syncprimitives which can be replaced withmea:tokio::sync::Barriercan bemea::barrier::Barriertokio::sync::oneshotcan bemea::oneshottokio::sync::Mutexcan bemea::mutex::Mutextokio::sync::broadcastis lackingThus, I think we can support the broadcast channel in mea to replace all
tokio::syncusage in foyer.Design and Implementation
The most common design is to use a circular queue, where senders put elements at the end, and each receiver tracks its current position and consumes new elements if any are available.
Some decision points:
tokio's broadcast would trigger a
Laggederror and forward the receiver's position to the oldest value contained by the channel.async-broadcast supports different overflow policy: (1) like what tokio's broadcast does, (2) sender waits for all the receivers to move forward.
Future&Wakermechanism?Typically, each receiver would consume elements until there are no more and register a waker on that cell. Once a sender puts a new element in that cell, it can wake up all the wakers so that receivers can consume the new elements.
The main point here is how we can efficiently mutate the shared circular queue and reduce lock usage as much as possible.
Besides, if we allow sender to wait on channel full, we may need to register wakers for wating senders.
Reference
cc @BewareMyPower @orthur2