#async-io #io #tokio #async #reconnect #automatic #traits

io-tether

定义 I/O 对象的特质,在失败时自动重新连接

5 个版本

0.1.3 2024 年 6 月 18 日
0.1.2 2024 年 6 月 15 日
0.1.1 2024 年 6 月 15 日
0.1.0 2024 年 6 月 15 日
0.0.1 2024 年 6 月 14 日

#373 in 异步

MIT 许可证

20KB
321 代码行

io-tether

定义 I/O 对象的特质,在失败时自动重新连接。

Crates.io | API 文档

此项目在范围上类似于 stubborn-io,但旨在利用最近稳定的特质中的 async fn,以便为最终用户简化重新连接的实现。

用法

要开始使用,请将 io-tether 添加到您的依赖项列表中

io-tether = { version = "0.1.3" }

然后,在大多数情况下,预计此库的消费者将希望在自己的类型上实现 TetherResolver。这使得他们能够在 I/O 尝试重新连接之前注入任意异步代码。

use io_tether::{TetherResolver, Context, State, Tether};
use tokio::{net::TcpStream, io::{AsyncReadExt, AsyncWriteExt}, sync::mpsc};

/// Custom resolver
pub struct CallbackResolver {
    channel: mpsc::Sender<String>,
}

impl TetherResolver for CallbackResolver {
    type Error = std::io::Error;

    async fn disconnected(
        &mut self,
        context: &Context,
        state: &State<Self::Error>,
    ) -> bool {
        match state {
            State::Eof => false, // No reconnection attempt will be made
            State::Err(error) => {
                let error = error.to_string();
                self.channel.send(error).await.unwrap();
                true
            }
        }
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut buf = Vec::new();
    let (channel, rx) = mpsc::channel(10);

    let listener = tokio::net::TcpListener::bind("localhost:8080").await?;
    tokio::spawn(async move {
        loop {
            let (mut stream, _addr) = listener.accept().await.unwrap();
            stream.write_all(b"foo-bar").await.unwrap();
            stream.shutdown().await.unwrap();
        }
    });

    let resolver = CallbackResolver {
        channel,
    };
    let mut tether = Tether::<_, TcpStream, _>::connect("localhost:8080", resolver)
        .await?;

    tether.read_to_end(&mut buf).await?;
    
    assert_eq!(&buf, b"foo-bar");

    Ok(())
}

稳定性

此项目仍然是一个非常正在进行中的项目。预计短期内会有相当常见的破坏性更改。

依赖关系

~2–10MB
~83K SLoC