#async-networking #async-io #async #non-blocking #service #future #io

motore

motore 是一个模块化和可重用组件库,用于构建健壮的客户端和服务器。motore 非常受 Tower 的启发。

10 个版本

0.4.1 2024 年 4 月 3 日
0.4.0 2023 年 10 月 23 日
0.3.3 2023 年 4 月 13 日
0.3.2 2023 年 2 月 15 日
0.0.0 2022 年 6 月 7 日

#49 in 异步

Download history 1837/week @ 2024-04-27 2520/week @ 2024-05-04 3422/week @ 2024-05-11 2487/week @ 2024-05-18 2188/week @ 2024-05-25 2464/week @ 2024-06-01 2000/week @ 2024-06-08 1701/week @ 2024-06-15 2459/week @ 2024-06-22 2761/week @ 2024-06-29 2764/week @ 2024-07-06 2089/week @ 2024-07-13 2400/week @ 2024-07-20 2463/week @ 2024-07-27 2689/week @ 2024-08-03 1643/week @ 2024-08-10

9,369 个月下载
用于 13 个 crate (5 个直接使用)

MIT/Apache

57KB
1K SLoC

Motore

Crates.io Documentation License Build Status

motore 是由 AFIT 和 RPITIT 驱动的异步中间件抽象。

围绕 motore,我们构建了模块化和可重用的组件,用于构建健壮的网络客户端和服务器。

motore 非常受 Tower 的启发。

概述

motore 使用 AFIT 和 RPITIT 来减轻编写异步代码的心理负担,特别是避免了使用 Box 的开销,从而让人不那么焦虑。

motore 的核心抽象是 Service 特性

pub trait Service<Cx, Request> {
    /// Responses given by the service.
    type Response;
    /// Errors produced by the service.
    type Error;

    /// Process the request and return the response asynchronously.
    async fn call(&self, cx: &mut Cx, req: Request) -> Result<Self::Response, Self::Error>;
}

入门

结合 AFIT 和 RPITIT,我们可以用非常简洁和易于阅读的方式编写异步代码。

pub struct Timeout<S> {
    inner: S,
    duration: Duration,
}

impl<Cx, Req, S> Service<Cx, Req> for Timeout<S>
where
    Req: 'static + Send,
    S: Service<Cx, Req> + 'static + Send + Sync,
    Cx: 'static + Send,
    S::Error: Send + Sync + Into<BoxError>,
{
    type Response = S::Response;

    type Error = BoxError;

    async fn call(&self, cx: &mut Cx, req: Req) -> Result<Self::Response, Self::Error> {
        let sleep = tokio::time::sleep(self.duration);
        tokio::select! {
            r = self.inner.call(cx, req) => {
                r.map_err(Into::into)
            },
            _ = sleep => Err(std::io::Error::new(std::io::ErrorKind::TimedOut, "service time out").into()),
        }
    }
}

我们还提供了 #[motore::service] 宏,使编写 Service 更加原生异步

use motore::service;

pub struct S<I> {
    inner: I,
}

#[service]
impl<Cx, Req, I> Service<Cx, Req> for S<I>
where
   Req: Send + 'static,
   I: Service<Cx, Req> + Send + 'static + Sync,
   Cx: Send + 'static,
{
    async fn call(&self, cx: &mut Cx, req: Req) -> Result<I::Response, I::Error> {
        self.inner.call(cx, req).await
    }
}

常见问题解答

在哪里可以找到 poll_ready(即背压)?

https://www.cloudwego.io/zh/docs/motore/faq/q1_pull_ready/

许可证

motore 在 MIT 许可证和 Apache 许可证(版本 2.0)下双许可。

有关详细信息,请参阅 LICENSE-MITLICENSE-APACHE

鸣谢

我们使用了一些第三方组件,并对他们的工作表示感谢。

有关完整列表,请参阅 CREDITS.md 文件。

社区

依赖

~2.9–4.5MB
~80K SLoC