[Resolved ]Help with perpetual tokio tcp stream

I am currently using a Framed<TcpStream, LinesCodec> inside of a perpetual futures loop, basically receiving messages and then sending them to an event handler. However, I would like to be able to continue functioning even if there are connectivity errors.

I would like to wrap the Tokio TcpStream in a custom struct PersistentTcp that acts just like the tokio one. The difference is that mine will try to reconnect to the same SocketAddr (for several attempts with exponential backoff) until it is successful. It should implement the same interface as the tokio one.

pub struct PersistentTcpStream {
    state: State,
    address: SocketAddr,
    reconnect_options: PersistentOptions,

type BoxedConnect = Box<Future<Item = TcpStream, Error = IoError> + Send + 'static>;

enum State {
    Reconnecting {
        connect_call: BoxedConnect,
        attempt_number: usize

Oddly, I’ve noticed that the framed object seems to only call tokio tcp’s Read, Write and Flush methods (from the std::io::Read and std::io::Write) instead of calling tokio tcp’s AsyncRead/AsyncWrite methods.

In general, I can detect a connection has failed/closed when the std::io read function returns a buffer of size 0.

When that occurs, I would like to invoke the tokio::TcpStream::connect method, but that returns a future, and I am figuring out about this disconnect in the synchronous read function. How can I somehow reconnect in a non blocking way?

I am unfortunately at a loss on how to do this. If the framed object was calling the Async Read and Write methods instead of the synchronous ones, then I would be able to return Async::NotReady until I polled the reconnect future to completion. Unfortunately, this is not possible from the synchronous methods.

Any help is appreciated.

Summarizing my question into a TLDR;

Why does it seem that is tokio::codec::Framed is only calling the io::Read and io::Write methods on my struct, and not the AsyncRead and AsyncWrite methods instead?


Basically, as a workaround I will just return WouldBlock from the sync io::Read call