{"id":17396327,"url":"https://github.com/ibraheemdev/firefly","last_synced_at":"2025-07-20T11:06:42.875Z","repository":{"id":37527104,"uuid":"500994572","full_name":"ibraheemdev/firefly","owner":"ibraheemdev","description":"High performance concurrent channels.","archived":false,"fork":false,"pushed_at":"2025-07-07T06:13:14.000Z","size":220,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-07-07T07:27:03.117Z","etag":null,"topics":[],"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/ibraheemdev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-06-07T20:29:49.000Z","updated_at":"2025-07-07T06:13:06.000Z","dependencies_parsed_at":"2023-01-19T11:34:05.632Z","dependency_job_id":null,"html_url":"https://github.com/ibraheemdev/firefly","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ibraheemdev/firefly","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ibraheemdev%2Ffirefly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ibraheemdev%2Ffirefly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ibraheemdev%2Ffirefly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ibraheemdev%2Ffirefly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ibraheemdev","download_url":"https://codeload.github.com/ibraheemdev/firefly/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ibraheemdev%2Ffirefly/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266112314,"owners_count":23878022,"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":[],"created_at":"2024-10-16T12:53:07.107Z","updated_at":"2025-07-20T11:06:42.834Z","avatar_url":"https://github.com/ibraheemdev.png","language":"Rust","readme":"# `firefly`\n\nA collection of high performance concurrent channels.\n\n```rust\n// create a SPSC channel with a capacity of 2\nlet (mut tx, mut rx) = firefly::spsc::bounded(2);\n\ntask::spawn(async move {\n    // send a message across asynchronously\n    tx.send(42).await.unwrap();\n});\n\n// receive the message synchronously\nassert_eq!(rx.recv_blocking().unwrap(), 42);\n```\n\n## Channel Flavors\n\nFirefly provides a variety of channel flavors, optimized for specific use cases:\n\n- [`spsc::bounded`](https://docs.rs/firefly/latest/firefly/spsc/fn.bounded.html)\n- [`spsc::unbounded`](https://docs.rs/firefly/latest/firefly/spsc/fn.unbounded.html)\n- [`mpsc::bounded`](https://docs.rs/firefly/latest/firefly/mpsc/fn.bounded.html)\n- [`mpsc::unbounded`](https://docs.rs/firefly/latest/firefly/mpsc/fn.unbounded.html)\n- [`mpmc::bounded`](https://docs.rs/firefly/latest/firefly/mpmc/fn.bounded.html)\n- [`mpmc::unbounded`](https://docs.rs/firefly/latest/firefly/mpmc/fn.unbounded.html)\n\nIn general, a channel flavor higher up on the list is likely to be more performant\nthan a more generic one lower down.\n\n---\n\nBounded channels are created with a bounded capacity; the maximum number of messages\nthat can be held at a given time:\n\n```rust\n// create a channel that can hold at most 8 messages at a time\nlet (mut tx, mut rx) = firefly::spsc::bounded(8);\n\ntask::spawn(async move {\n    for i in 0..100 {\n        // send a message, potentially waiting until capacity frees up\n        tx.send(i).await.unwrap();\n    }\n});\n\n// block until messages are sent\nwhile let Ok(i) = rx.recv_blocking() {\n    println!(\"{i}\");\n}\n```\n\nUnbounded channels on the other hand are unlimited in their capacity, meaning that\nsending never blocks:\n\n```rust\n// create an unbounded channel\nlet (mut tx, mut rx) = firefly::spsc::unbounded();\n\ntask::spawn(async move {\n    // send an arbitrary amount of messages\n    for i in 0..10_000 {\n        tx.send(i).unwrap();\n    }\n});\n\n// block until all messages are sent\nwhile let Ok(i) = rx.recv_blocking() {\n    println!(\"{i}\");\n}\n```\n\n## Blocking\n\nSend and receive operations can be performed four different ways:\n\n- Non-blocking (returns immediately with success or failure).\n- Asynchronously (blocks the async task).\n- Blocking (blocks the thread until the operation succeeds or the channel disconnects).\n- Blocking with a timeout (blocks upto a maximum duration of time).\n\n```rust\nlet (mut tx, mut rx) = firefly::spsc::bounded(4);\n\nthread::spawn(move || {\n    for _ in 0..3 {\n        // this can never fail because we never exceed the capacity\n        tx.try_send(42).unwrap();\n    }\n});\n\n// attempt to receive the message without blocking\nmatch rx.try_recv() {\n    Ok(x) =\u003e assert_eq!(x, 42),\n    Err(_) =\u003e println!(\"message has not been sent yet\")\n}\n\n// block until the message is sent\nassert_eq!(rx.recv_blocking(), Ok(42));\n\n// block for at most 1 second\nmatch rx.recv_blocking_timeout(Duration::from_secs(1)) {\n    Ok(x) =\u003e assert_eq!(x, 42),\n    Err(_) =\u003e println!(\"message took too long to send\")\n}\n\n// spawn a task that receives the message asynchronously\ntask::spawn(async move {\n    assert_eq!(rx.recv().await, Ok(42));\n});\n```\n\nAll channels can be used to \"bridge\" between async and sync code:\n\n```rust\nlet (mut tx, mut rx) = firefly::spsc::bounded(8);\n\n// send messages synchronously\nthread::spawn(move || {\n    for i in 0..16 {\n        tx.send_blocking(i).unwrap()\n    }\n});\n\n// receive asynchronously\ntask::spawn(async move {\n    while let Ok(i) = rx.recv().await {\n        println!(\"{i}\");\n    }\n});\n```\n\n## Disconnection\n\nWhen all senders or receivers of a given channel are dropped, the channel is\ndisconnected. Any attempts to send a message will fail. Any remaining messages\nin the channel can be received, but subsequent attempts to receive will also\nfail:\n\n```rust\nlet (mut tx, mut rx) = firefly::spsc::unbounded();\n\ntx.send(1).unwrap();\ntx.send(2).unwrap();\n\n// disconnect the sender\ndrop(tx);\n\n// any remaining messages can be received\nassert_eq!(rx.recv().await, Ok(1));\nassert_eq!(rx.recv().await, Ok(2));\n\n// subsequent attempts will error\nassert_eq!(rx.recv().await, Err(firefly::RecvError));\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fibraheemdev%2Ffirefly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fibraheemdev%2Ffirefly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fibraheemdev%2Ffirefly/lists"}