-
-
Notifications
You must be signed in to change notification settings - Fork 12
Description
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::Barriercan bemea::barrier::Barriertokio::sync::oneshotcan bemea::oneshottokio::sync::Mutexcan bemea::mutex::Mutextokio::sync::broadcastis 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&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.