{"id":19674662,"url":"https://github.com/cloudwego/motore","last_synced_at":"2025-05-15T02:05:15.080Z","repository":{"id":59144760,"uuid":"500724932","full_name":"cloudwego/motore","owner":"cloudwego","description":"Async middleware abstraction powered by AFIT and RPITIT.","archived":false,"fork":false,"pushed_at":"2025-01-24T06:13:01.000Z","size":418,"stargazers_count":256,"open_issues_count":3,"forks_count":24,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-04-06T21:09:07.597Z","etag":null,"topics":["middleware","rust"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/motore","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloudwego.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE-APACHE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":"SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-07T06:57:06.000Z","updated_at":"2025-04-05T14:12:23.000Z","dependencies_parsed_at":"2024-12-20T09:03:19.730Z","dependency_job_id":"581ce6a1-f5a6-4b38-acba-4a112fd78f09","html_url":"https://github.com/cloudwego/motore","commit_stats":{"total_commits":31,"total_committers":6,"mean_commits":5.166666666666667,"dds":0.6129032258064516,"last_synced_commit":"215cd1b4f3ff3db72121c6a49470f23385932457"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudwego%2Fmotore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudwego%2Fmotore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudwego%2Fmotore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudwego%2Fmotore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudwego","download_url":"https://codeload.github.com/cloudwego/motore/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248799904,"owners_count":21163400,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["middleware","rust"],"created_at":"2024-11-11T17:19:17.256Z","updated_at":"2025-04-13T23:50:58.216Z","avatar_url":"https://github.com/cloudwego.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Motore](https://github.com/cloudwego/motore/raw/main/.github/assets/logo.png?sanitize=true)\n\n[![Crates.io](https://img.shields.io/crates/v/motore)](https://crates.io/crates/motore)\n[![Documentation](https://docs.rs/motore/badge.svg)](https://docs.rs/motore)\n[![License](https://img.shields.io/crates/l/motore)](#license)\n[![Build Status][actions-badge]][actions-url]\n\n[actions-badge]: https://github.com/cloudwego/motore/actions/workflows/ci.yaml/badge.svg\n[actions-url]: https://github.com/cloudwego/motore/actions\n\nMotore is an async middleware abstraction powered by AFIT and RPITIT.\n\nAround Motore, we build modular and reusable components for building robust networking clients and servers.\n\nMotore is greatly inspired by [`Tower`][tower].\n\n[tower]: https://github.com/tower-rs/tower\n\n## Overview\n\nMotore uses AFIT and RPITIT to reduce the mental burden of writing asynchronous code, especially to avoid the overhead of `Box` to make people less anxious.\n\nThe core abstraciton of Motore is the `Service` trait:\n\n```rust\npub trait Service\u003cCx, Request\u003e {\n    /// Responses given by the service.\n    type Response;\n    /// Errors produced by the service.\n    type Error;\n\n    /// Process the request and return the response asynchronously.\n    async fn call(\u0026self, cx: \u0026mut Cx, req: Request) -\u003e Result\u003cSelf::Response, Self::Error\u003e;\n}\n```\n\n## Getting Started\n\nCombing AFIT and RPITIT together, we can write asynchronous code in a very concise and readable way.\n\n```rust\npub struct Timeout\u003cS\u003e {\n    inner: S,\n    duration: Duration,\n}\n\nimpl\u003cCx, Req, S\u003e Service\u003cCx, Req\u003e for Timeout\u003cS\u003e\nwhere\n    Req: 'static + Send,\n    S: Service\u003cCx, Req\u003e + 'static + Send + Sync,\n    Cx: 'static + Send,\n    S::Error: Send + Sync + Into\u003cBoxError\u003e,\n{\n    type Response = S::Response;\n\n    type Error = BoxError;\n\n    async fn call(\u0026self, cx: \u0026mut Cx, req: Req) -\u003e Result\u003cSelf::Response, Self::Error\u003e {\n        let sleep = tokio::time::sleep(self.duration);\n        tokio::select! {\n            r = self.inner.call(cx, req) =\u003e {\n                r.map_err(Into::into)\n            },\n            _ = sleep =\u003e Err(std::io::Error::new(std::io::ErrorKind::TimedOut, \"service time out\").into()),\n        }\n    }\n}\n```\n\nWe also provided the `#[motore::service]` macro to make writing a `Serivce` more async-native:\n\n```rust\nuse motore::service;\n\npub struct S\u003cI\u003e {\n    inner: I,\n}\n\n#[service]\nimpl\u003cCx, Req, I\u003e Service\u003cCx, Req\u003e for S\u003cI\u003e\nwhere\n   Req: Send + 'static,\n   I: Service\u003cCx, Req\u003e + Send + 'static + Sync,\n   Cx: Send + 'static,\n{\n    async fn call(\u0026self, cx: \u0026mut Cx, req: Req) -\u003e Result\u003cI::Response, I::Error\u003e {\n        self.inner.call(cx, req).await\n    }\n}\n```\n\n## FAQ\n\n### Where's the `poll_ready`(a.k.a. backpressure)?\n\nhttps://www.cloudwego.io/docs/volo/faq/#where-did-poll_ready-backpressure-go\n\n## License\n\nMotore is dual-licensed under the MIT license and the Apache License (Version 2.0).\n\nSee [LICENSE-MIT](https://github.com/cloudwego/motore/blob/main/LICENSE-MIT) and [LICENSE-APACHE](https://github.com/cloudwego/motore/blob/main/LICENSE-APACHE) for details.\n\n## Credits\n\nWe have used some third party components, and we thank them for their work.\n\nFor the full list, you may refer to the [CREDITS.md](https://github.com/cloudwego/motore/blob/main/CREDITS.md) file.\n\n## Community\n\n- Email: [motore@cloudwego.io](mailto:motore@cloudwego.io)\n- How to become a member: [COMMUNITY MEMBERSHIP](https://github.com/cloudwego/community/blob/main/COMMUNITY_MEMBERSHIP.md)\n- Issues: [Issues](https://github.com/cloudwego/motore/issues)\n- Feishu: Scan the QR code below with [Feishu](https://www.feishu.cn/) or [click this link](https://applink.feishu.cn/client/chat/chatter/add_by_link?link_token=a17m50a7-79cd-4ece-b14c-c1586e1aa636) to join our CloudWeGo Motore user group.\n\n  \u003cimg src=\"https://github.com/cloudwego/motore/raw/main/.github/assets/motore-feishu-user-group.png\" alt=\"Motore user group\" width=\"50%\" height=\"50%\" /\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudwego%2Fmotore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudwego%2Fmotore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudwego%2Fmotore/lists"}