{"id":20696948,"url":"https://github.com/smol-rs/async-broadcast","last_synced_at":"2025-05-14T20:04:25.655Z","repository":{"id":38413264,"uuid":"294735661","full_name":"smol-rs/async-broadcast","owner":"smol-rs","description":"Async broadcast channels","archived":false,"fork":false,"pushed_at":"2024-12-23T21:11:36.000Z","size":116,"stargazers_count":175,"open_issues_count":2,"forks_count":26,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-06T22:01:43.367Z","etag":null,"topics":["async","rust"],"latest_commit_sha":null,"homepage":"","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/smol-rs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE-APACHE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-09-11T15:42:13.000Z","updated_at":"2025-03-23T05:02:43.000Z","dependencies_parsed_at":"2023-07-14T08:53:07.108Z","dependency_job_id":"dfce6911-0bba-4f99-ae72-6dc16a6e663f","html_url":"https://github.com/smol-rs/async-broadcast","commit_stats":null,"previous_names":["yoshuawuyts/broadcast-channel"],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smol-rs%2Fasync-broadcast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smol-rs%2Fasync-broadcast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smol-rs%2Fasync-broadcast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smol-rs%2Fasync-broadcast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smol-rs","download_url":"https://codeload.github.com/smol-rs/async-broadcast/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248804781,"owners_count":21164131,"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":["async","rust"],"created_at":"2024-11-17T00:16:05.733Z","updated_at":"2025-04-14T00:52:21.280Z","avatar_url":"https://github.com/smol-rs.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# async-broadcast\n\n[![Build](https://github.com/smol-rs/async-broadcast/workflows/Build%20and%20test/badge.svg)](\nhttps://github.com/smol-rs/async-broadcast/actions)\n[![License](https://img.shields.io/badge/license-Apache--2.0_OR_MIT-blue.svg)](\nhttps://github.com/smol-rs/async-broadcast)\n[![Cargo](https://img.shields.io/crates/v/async-broadcast.svg)](\nhttps://crates.io/crates/async-broadcast)\n[![Documentation](https://docs.rs/async-broadcast/badge.svg)](\nhttps://docs.rs/async-broadcast)\n\nAn async multi-producer multi-consumer broadcast channel, where each consumer gets a clone of every\nmessage sent on the channel. For obvious reasons, the channel can only be used to broadcast types\nthat implement `Clone`.\n\nA channel has the `Sender` and `Receiver` side. Both sides are cloneable and can be shared\namong multiple threads.\n\nWhen all `Sender`s or all `Receiver`s are dropped, the channel becomes closed. When a channel is\nclosed, no more messages can be sent, but remaining messages can still be received.\n\nThe channel can also be closed manually by calling `Sender::close()` or\n`Receiver::close()`.\n\n## Examples\n\n```rust\nuse async_broadcast::{broadcast, TryRecvError};\nuse futures_lite::{future::block_on, stream::StreamExt};\n\nblock_on(async move {\n    let (s1, mut r1) = broadcast(2);\n    let s2 = s1.clone();\n    let mut r2 = r1.clone();\n\n    // Send 2 messages from two different senders.\n    s1.broadcast(7).await.unwrap();\n    s2.broadcast(8).await.unwrap();\n\n    // Channel is now at capacity so sending more messages will result in an error.\n    assert!(s2.try_broadcast(9).unwrap_err().is_full());\n    assert!(s1.try_broadcast(10).unwrap_err().is_full());\n\n    // We can use `recv` method of the `Stream` implementation to receive messages.\n    assert_eq!(r1.next().await.unwrap(), 7);\n    assert_eq!(r1.recv().await.unwrap(), 8);\n    assert_eq!(r2.next().await.unwrap(), 7);\n    assert_eq!(r2.recv().await.unwrap(), 8);\n\n    // All receiver got all messages so channel is now empty.\n    assert_eq!(r1.try_recv(), Err(TryRecvError::Empty));\n    assert_eq!(r2.try_recv(), Err(TryRecvError::Empty));\n\n    // Drop both senders, which closes the channel.\n    drop(s1);\n    drop(s2);\n\n    assert_eq!(r1.try_recv(), Err(TryRecvError::Closed));\n    assert_eq!(r2.try_recv(), Err(TryRecvError::Closed));\n})\n```\n\n## Difference with `async-channel`\n\nThis crate is similar to [`async-channel`] in that they both provide an MPMC channel but the main\ndifference being that in `async-channel`, each message sent on the channel is only received by one\nof the receivers. `async-broadcast` on the other hand, delivers each message to every receiver\n(IOW broadcast) by cloning it for each receiver.\n\n[`async-channel`]: https://crates.io/crates/async-channel\n\n## Difference with other broadcast crates\n\n* [`broadcaster`]: The main difference would be that `broadcaster` doesn't have a sender and\n  receiver split and both sides use clones of the same BroadcastChannel instance. The messages are\n  sent are sent to all channel clones. While this can work for many cases, the lack of sender and\n  receiver split, means that often times, you'll find yourself having to drain the channel on the\n  sending side yourself.\n\n* [`postage`]: this crate provides a [broadcast API][pba] similar to `async_broadcast`. However, it:\n  - (at the time of this writing) duplicates [futures] API, which isn't ideal.\n  - Does not support overflow mode nor has the concept of inactive receivers, so a slow or inactive\n    receiver blocking the whole channel is not a solvable problem.\n  - Provides all kinds of channels, which is generally good but if you just need a broadcast\n    channel, `async_broadcast` is probably a better choice.\n\n* [`tokio::sync`]: Tokio's `sync` module provides a [broadcast channel][tbc] API. The differences\n   here are:\n  - While this implementation does provide [overflow mode][tom], it is the default behavior and not\n    opt-in.\n  - There is no equivalent of inactive receivers.\n  - While it's possible to build tokio with only the `sync` module, it comes with other APIs that\n    you may not need.\n\n[`broadcaster`]: https://crates.io/crates/broadcaster\n[`postage`]: https://crates.io/crates/postage\n[pba]: https://docs.rs/postage/0.4.1/postage/broadcast/fn.channel.html\n[futures]: https://crates.io/crates/futures\n[`tokio::sync`]: https://docs.rs/tokio/1.6.0/tokio/sync\n[tbc]: https://docs.rs/tokio/1.6.0/tokio/sync/broadcast/index.html\n[tom]: https://docs.rs/tokio/1.6.0/tokio/sync/broadcast/index.html#lagging\n\n## Safety\nThis crate uses ``#![deny(unsafe_code)]`` to ensure everything is implemented in\n100% Safe Rust.\n\n## Contributing\nWant to join us? Check out our [\"Contributing\" guide][contributing] and take a\nlook at some of these issues:\n\n- [Issues labeled \"good first issue\"][good-first-issue]\n- [Issues labeled \"help wanted\"][help-wanted]\n\n[contributing]: https://github.com/smol-rs/async-broadcast/blob/master/.github/CONTRIBUTING.md\n[good-first-issue]: https://github.com/smol-rs/async-broadcast/labels/good%20first%20issue\n[help-wanted]: https://github.com/smol-rs/async-broadcast/labels/help%20wanted\n\n## License\n\n\u003csup\u003e\nLicensed under either of \u003ca href=\"LICENSE-APACHE\"\u003eApache License, Version\n2.0\u003c/a\u003e or \u003ca href=\"LICENSE-MIT\"\u003eMIT license\u003c/a\u003e at your option.\n\u003c/sup\u003e\n\n\u003cbr/\u003e\n\n\u003csub\u003e\nUnless you explicitly state otherwise, any contribution intentionally submitted\nfor inclusion in this crate by you, as defined in the Apache-2.0 license, shall\nbe dual licensed as above, without any additional terms or conditions.\n\u003c/sub\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmol-rs%2Fasync-broadcast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmol-rs%2Fasync-broadcast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmol-rs%2Fasync-broadcast/lists"}