{"id":13875971,"url":"https://github.com/popzxc/messages-rs","last_synced_at":"2025-08-20T06:32:46.743Z","repository":{"id":44876934,"uuid":"284654084","full_name":"popzxc/messages-rs","owner":"popzxc","description":"Runtime-agnostic actor library","archived":false,"fork":false,"pushed_at":"2023-06-13T13:05:54.000Z","size":121,"stargazers_count":76,"open_issues_count":0,"forks_count":1,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-12-15T23:45:14.093Z","etag":null,"topics":["actors","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/popzxc.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-08-03T09:09:56.000Z","updated_at":"2024-12-12T01:34:48.000Z","dependencies_parsed_at":"2024-01-13T19:41:31.478Z","dependency_job_id":"57018a58-89cf-47df-8979-e51ff903e458","html_url":"https://github.com/popzxc/messages-rs","commit_stats":{"total_commits":133,"total_committers":2,"mean_commits":66.5,"dds":0.007518796992481258,"last_synced_commit":"841a27b2ed8297e27e373380c9da3501cfa59f2e"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/popzxc%2Fmessages-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/popzxc%2Fmessages-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/popzxc%2Fmessages-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/popzxc%2Fmessages-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/popzxc","download_url":"https://codeload.github.com/popzxc/messages-rs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230400615,"owners_count":18219831,"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":["actors","rust"],"created_at":"2024-08-06T06:00:53.048Z","updated_at":"2024-12-19T08:08:23.447Z","avatar_url":"https://github.com/popzxc.png","language":"Rust","funding_links":[],"categories":["Rust","rust"],"sub_categories":[],"readme":"# Messages. Convenient asynchronous communication\n\n**Status:**\n[![CI](https://github.com/popzxc/messages-rs/workflows/CI/badge.svg)](https://github.com/popzxc/messages-rs/actions)\n\n**Project info:**\n[![Docs.rs](https://docs.rs/messages/badge.svg)](https://docs.rs/messages)\n[![Latest Version](https://img.shields.io/crates/v/messages.svg)](https://crates.io/crates/messages)\n[![License](https://img.shields.io/github/license/popzxc/messages-rs.svg)](https://github.com/popzxc/messages-rs)\n![Rust 1.50+ required](https://img.shields.io/badge/rust-1.50+-blue.svg?label=Rust)\n\n## Description\n\n`messages` is a runtime-agnostic actor library.\n\nIt is heavily inspired by [`actix`][actix], a great actor framework.\n\nThis crate can be used with any runtime, whether it's popular or not.\nHowever, for the biggest one (`tokio` and `async-std`) there is an optional\nbuilt-in support enabling more convenient interface (such as an automatic\nactor spawning).\n\n[actix]: https://crates.io/crates/actix\n\n## Key features\n\n- Full runtime independence. Can be used with any possible runtime that can spawn futures.\n- Low dependencies amount.\n- Low amount of boilerplate without derive macros.\n- Good performance (close to raw channels).\n- Relevant (but sufficient) functionality only.\n\n## Which library should I choose?\n\n`actix` is a great, thoughtful, polished, and optimized library. If it is *possible*\nfor you, you should consider it as the main option.\n\nHowever, if any of statements below apply to your use case, `messages` may be better:\n\n- You can't or don't want to stick to the Actix runtime.\n- Your tasks may not have the similar runtime expense (`actix-rt` does not have work stealing\n  and thus some threads may be underloaded in that case).\n- You are seeking for the simpler interface and don't want to implement asynchronous code atop\n  of the initially sync interface.\n  \n**But what about [`xactor`](https://crates.io/crates/xactor)?**\n\n`xactor` is another good library inspired by Actix. It initially was built for `async-std` but\nthen gained `tokio` support.\n\nNonetheless, this library is not runtime-agnostic. It supports `async-std` and `tokio` v1, but\nis not (yet) compatible with another runtimes.\n\nThat being said, `messages` initially serves different purpose: provide a way to implement\nactor workflow without having to think about supported runtimes.\n\n## Asyncness\n\nThis library is async-first, meaning that everything is made with respect to asynchronous architecture.\nWhile in *some* cases synchronous interfaces could've been more performant, it'd make the interface much\nmore bloated. If synchronous actor interface is preferred, consider using `actix`, as it provides one.\n\n## Performance\n\nTL;DR: This library provides performance that is better than in `actix` (for **asynchronous** message handling; \nbased on the ring benchmark used by `actix` itself) and is tied with `futures` channels.\n\nMore details are presented in the [BENCHES.md](./BENCHES.md).\n\n*Note:* `messages` treats `async` and multi-threaded context as its main environment,\nthus it may be less suitable (or, more precisely, less efficient) for the partially\nsync context. For instance, the sync version of the ring benchmark is by 80% faster than this library.\n\n## Examples\n\n### With runtime features\n\n```rust\nuse messages::prelude::*;\n\nstruct Example; // Most of the types can be an actor.\n\n// While `Actor` implementation can be customized, it is not required.\n#[async_trait]\nimpl Actor for Example {}\n\n// Message handler that calculates sum of two numbers.\n#[async_trait]\nimpl Handler\u003c(u8, u8)\u003e for Example {\n    type Result = u16;\n    async fn handle(\u0026mut self, (a, b): (u8, u8), context: \u0026Context\u003cSelf\u003e) -\u003e u16 {\n        (a as u16) + (b as u16)\n    }\n}\n\n// Notification handler that just writes received number to stdout.\n#[async_trait]\nimpl Notifiable\u003cu8\u003e for Example {\n    async fn notify(\u0026mut self, input: u8, context: \u0026Context\u003cSelf\u003e) {\n        println!(\"Received number {}\", input);\n    }\n}\n\n#[tokio::main]\nasync fn main() {\n   let mut addr = Example.spawn();\n   let result = addr.send((22, 20)).await.unwrap();\n   assert_eq!(result, 42);\n   addr.notify(42).await.unwrap();\n   addr.stop().await;\n   addr.wait_for_stop().await;  \n}\n```\n\n### Without runtime features\n\n```rust\nuse messages::prelude::*;\n\nstruct Ping;\n\n#[async_trait]\nimpl Actor for Ping {}\n\n#[async_trait]\nimpl Handler\u003cu8\u003e for Ping {\n    type Result = u8;\n    async fn handle(\u0026mut self, input: u8, context: \u0026Context\u003cSelf\u003e) -\u003e u8 {\n        input\n    }\n}\n\n#[tokio::main]\nasync fn main() {\n   let context = Context::new();\n   let mut addr = context.address();\n   let actor = Ping;\n   // Could've been any other runtime.\n   let mut task_handle = tokio::spawn(context.run(actor));\n   let result = addr.send(42).await.unwrap();\n   assert_eq!(result, 42);\n   addr.stop().await;\n   addr.wait_for_stop().await;\n   task_handle.await.unwrap();\n}\n```\n\n### More\n\nMore examples can be found in the [examples](./examples) directory.\n\nThey are numbered and written in a manner so that the next example is always somewhat superior to the\nprevious one. You can consider it to be a temporary alternative for a book (which is coming later).\n\nList of currently provided examples:\n\n- [Ping](./examples/01_ping.rs): Simple ping actor without much of functionality.\n- [Notify](./examples/02_notify.rs): More verbose example showing capabilities of the actor interface.\n- [Fibonacci](./examples/03_fibonacci.rs): Example of a coroutine actor, i.e. one that can process messages in parallel.\n- [Ring](./examples/04_ring.rs): Ring benchmark, mostly copied from the corresponding `actix` example.\n- [Timed stream](./examples/05_timed_stream.rs): Example showing both how to attach stream to an actor and send timed notifications to it.\n- [`async-std`](./examples/06_async_std.rs): Version of the `Notify` example adapted for `async-std` runtime.\n- [`smol`](./examples/07_no_runtime.rs): Example of using a runtime not supported out of the box. In that case, `smol`.\n- [WebSocket](./examples/08_websocket.rs): Simple actor-based echo websocket server (and a client to play with it).\n\n\n## Contributing\n\nAll kinds of contributions are really appreciated!\n\n## License\n\n`messages` library is licensed under the MIT License. See [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpopzxc%2Fmessages-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpopzxc%2Fmessages-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpopzxc%2Fmessages-rs/lists"}