-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
What is tokio::io::simplex?
It is a single producer, single consumer, and async byte stream channel.
Why deprecate tokio::io::simplex?
It is easy to make it hanges forever, and hard to fix this bug without breaking change, see #6914.
It might be hard for the existing downstream consumer to migrate to another implementation, however, we can courage the new downstream use a well behaved alternative.
Why add the alternative to the tokio-util instead of tokio?
The motivation is keep the tokio crate itself slim.
simplex is essentially a utility, which is not highly coupled with the async runtime. This also open more space when we want to do breaking change for utilities, because it is much easier to make a breaking change in tokio-util compared to tokio.
Enforce the backpressure handling
simplex acts on in-memory buffer, and its reader and writer are typically used by different component. the consequences of not dealing with the backpressure properly are even more obvious for simplex.
We want simplex itself to enforce backpressure handling for the convenience of downstream.
Implement the AsyncBufRead
AsyncBufReadSince simplex acts on a in-memory buffer, it makes sense to implement AsyncBufRead, otherwise downstream may wrap the simplex by BufReader, which doesn't make sense. Implementing these two trait sends the signal to prevent downstream from doing these kind of useless thing.
It is hard to implement AsyncBufRead for simplex because the AsyncBufRead::poll_fill_buf return an &[u8], it doesn't work with Mutex or atomic SPSC. Instead, I chose to mention the downside of wrapping the simplex using BufReader.
Why not mention high-level implementation here?
Single producer, single consumer queue is a solved problem. We have many examples to refer to, and it is not complicated. So discussing this here wouldn't be such helpful.