{"id":13484726,"url":"https://github.com/dwango/fibers-rs","last_synced_at":"2026-04-06T06:03:16.193Z","repository":{"id":48358962,"uuid":"75369624","full_name":"dwango/fibers-rs","owner":"dwango","description":"A Rust library to execute a number of lightweight asynchronous tasks (a.k.a, fibers) based on futures and mio.","archived":false,"fork":false,"pushed_at":"2021-03-29T09:52:49.000Z","size":254,"stargazers_count":189,"open_issues_count":5,"forks_count":11,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-12-14T05:22:41.405Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/dwango.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":"2016-12-02T06:57:11.000Z","updated_at":"2025-12-12T02:13:35.000Z","dependencies_parsed_at":"2022-09-26T20:10:55.265Z","dependency_job_id":null,"html_url":"https://github.com/dwango/fibers-rs","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/dwango/fibers-rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwango%2Ffibers-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwango%2Ffibers-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwango%2Ffibers-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwango%2Ffibers-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dwango","download_url":"https://codeload.github.com/dwango/fibers-rs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dwango%2Ffibers-rs/sbom","scorecard":{"id":361090,"data":{"date":"2025-08-11","repo":{"name":"github.com/dwango/fibers-rs","commit":"58d5303b78d0d0eb4456a34589b9d3ca901e4554"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":7,"reason":"Found 10/14 approved changesets -- score normalized to 7","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 27 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T10:52:21.292Z","repository_id":48358962,"created_at":"2025-08-18T10:52:21.292Z","updated_at":"2025-08-18T10:52:21.292Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31461534,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T21:22:52.476Z","status":"online","status_checked_at":"2026-04-06T02:00:07.287Z","response_time":112,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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-07-31T17:01:31.668Z","updated_at":"2026-04-06T06:03:16.153Z","avatar_url":"https://github.com/dwango.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":["Databases"],"readme":"fibers\n======\n\n[![fibers](http://meritbadge.herokuapp.com/fibers)](https://crates.io/crates/fibers)\n[![Documentation](https://docs.rs/fibers/badge.svg)](https://docs.rs/fibers)\n[![Build Status](https://travis-ci.org/dwango/fibers-rs.svg?branch=master)](https://travis-ci.org/dwango/fibers-rs)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\nThis is a library to execute a number of lightweight asynchronous tasks (a.k.a, fibers).\n\n[Documentation](https://docs.rs/fibers/)\n\nNote that `fibers` heavily uses [futures](https://github.com/alexcrichton/futures-rs) to\nrepresent asynchronous task. If you are not familiar with it,\nwe recommend that you refer the `README.md` and `TUTORIAL.md` of [futures](https://github.com/alexcrichton/futures-rs)\nbefore reading the following.\n\nThis library also uses [mio](https://github.com/carllerche/mio) to achieve\nefficient asynchronous I/O handling (mainly for networking primitives).\nHowever, its existence is hidden from the user, so you do not usually have to worry about it.\n\n---\n\n`Future` is an excellent way to represent asynchronous task.\nIt is intuitive, easily composed with other futures to represent a complicated task,\nwithout runtime overhead.\nBut, there is a remaining problem that\n\"How to efficiently execute (possibility a very large amount of) concurrent tasks?\".\n`fibers` is an answer to the problem.\n\nConceptually, the responsibility of `fibers` is very simple.\nIt represents an asynchronous task (a.k.a., fiber) as a future instance.\nAnd there is an executor that takes futures and executes them like following.\n\n```rust\n// Creates an executor.\nlet mut executor = ThreadPoolExecutor::new().unwrap();\n\n// Spawns fibers (i.e., passes futures to the executor).\nexecutor.spawn(futures::lazy(|| { println!(\"Hello\"); Ok(())} ));\nexecutor.spawn(futures::lazy(|| { println!(\"World!\"); Ok(())} ));\n\n// Executes them.\nexecutor.run().unwrap();\n```\n\nFibers may be run on different background threads, but the user does not need to notice it.\nIf it runs on machines with a large number of processors, performance will improve naturally.\n\nRoughly speaking, if a future returns `Async::NotReady` response to a call of `Future::poll` method,\nthe fiber associated with the future will move into the \"waiting\" state.\nThen, it is suspended (descheduled) until any event in which the future is interested happens\n(e.g., waits until data is arrived on a target TCP socket).\nFinally, if a future returns `Async::Ready` response, the fiber will be regarded as completed and\nthe executor will drop the fiber.\n\nThis library provides primitives for writing programs in an efficient\nasynchronous fashion (See documentations of [net](https://docs.rs/fibers/0.1/fibers/net/index.html),\n[sync](https://docs.rs/fibers/0.1/fibers/sync/index.html), [io](https://docs.rs/fibers/0.1/fibers/io/index.html),\n[time](https://docs.rs/fibers/0.1/fibers/time/index.html) modules for more details).\n\nThe main concern of this library is \"how to execute fibers\".\nSo it is preferred to use external crates (e.g., [handy_async](https://github.com/sile/handy_async))\nto describe \"how to represent asynchronous tasks\".\n\n\nInstallation\n------------\n\nFirst, add following lines to your `Cargo.toml`:\n\n```toml\n[dependencies]\nfibers = \"0.1\"\nfutures = \"0.1\"  # In practical, `futures` is mandatory to use `fibers`.\n```\n\nNext, add this to your crate:\n\n```rust\nextern crate fibers;\nextern crate futures;\n```\n\nSeveral runnable examples are given in the next section.\n\n\nExamples\n--------\n\nThe following are examples of writing code to perform asynchronous tasks.\n\nOther examples are found in \"fibers/examples\" directory.\nAnd you can run an example by executing the following command.\n\n```bash\n$ cargo run --example ${EXAMPLE_NAME}\n```\n\n### Calculation of fibonacci numbers\n\n```rust\n// See also: \"fibers/examples/fibonacci.rs\"\nextern crate fibers;\nextern crate futures;\n\nuse fibers::{Spawn, Executor, ThreadPoolExecutor};\nuse futures::Future;\n\nfn main() {\n    // Creates an executor instance.\n    let mut executor = ThreadPoolExecutor::new().unwrap();\n\n    // Creates a future which will calculate the fibonacchi number of `10`.\n    let input_number = 10;\n    let future = fibonacci(input_number, executor.handle());\n\n    // Spawns and executes the future (fiber).\n    let monitor = executor.spawn_monitor(future);\n    let answer = executor.run_fiber(monitor).unwrap();\n\n    // Checkes the answer.\n    assert_eq!(answer, Ok(55));\n}\n\nfn fibonacci\u003cH: Spawn + Clone\u003e(n: usize, handle: H) -\u003e Box\u003cdyn Future\u003cItem=usize, Error=()\u003e + Send\u003e {\n    if n \u003c 2 {\n        Box::new(futures::finished(n))\n    } else {\n        /// Spawns a new fiber per recursive call.\n        let f0 = handle.spawn_monitor(fibonacci(n - 1, handle.clone()));\n        let f1 = handle.spawn_monitor(fibonacci(n - 2, handle.clone()));\n        Box::new(f0.join(f1).map(|(a0, a1)| a0 + a1).map_err(|_| ()))\n    }\n}\n```\n\n### TCP Echo Server and Client\n\nAn example of TCP echo server listening at the address \"127.0.0.1:3000\":\n\n```rust\n// See also: \"fibers/examples/tcp_echo_srv.rs\"\nextern crate fibers;\nextern crate futures;\nextern crate handy_async;\n\nuse std::io;\nuse fibers::{Spawn, Executor, ThreadPoolExecutor};\nuse fibers::net::TcpListener;\nuse futures::{Future, Stream};\nuse handy_async::io::{AsyncWrite, ReadFrom};\nuse handy_async::pattern::AllowPartial;\n\nfn main() {\n    let server_addr = \"127.0.0.1:3000\".parse().expect(\"Invalid TCP bind address\");\n\n    let mut executor = ThreadPoolExecutor::new().expect(\"Cannot create Executor\");\n    let handle0 = executor.handle();\n    let monitor = executor.spawn_monitor(TcpListener::bind(server_addr)\n        .and_then(move |listener| {\n            println!(\"# Start listening: {}: \", server_addr);\n\n            // Creates a stream of incoming TCP client sockets\n            listener.incoming().for_each(move |(client, addr)| {\n                // New client is connected.\n                println!(\"# CONNECTED: {}\", addr);\n                let handle1 = handle0.clone();\n\n                // Spawns a fiber to handle the client.\n                handle0.spawn(client.and_then(move |client| {\n                        // For simplicity, splits reading process and\n                        // writing process into differrent fibers.\n                        let (reader, writer) = (client.clone(), client);\n                        let (tx, rx) = fibers::sync::mpsc::channel();\n\n                        // Spawns a fiber for the writer side.\n                        // When a message is arrived in `rx`,\n                        // this fiber sends it back to the client.\n                        handle1.spawn(rx.map_err(|_| -\u003e io::Error { unreachable!() })\n                            .fold(writer, |writer, buf: Vec\u003cu8\u003e| {\n                                println!(\"# SEND: {} bytes\", buf.len());\n                                writer.async_write_all(buf).map(|(w, _)| w).map_err(|e| e.into_error())\n                            })\n                            .then(|r| {\n                                println!(\"# Writer finished: {:?}\", r);\n                                Ok(())\n                            }));\n\n                        // The reader side is executed in the current fiber.\n                        let stream = vec![0;1024].allow_partial().into_stream(reader);\n                        stream.map_err(|e| e.into_error())\n                            .fold(tx, |tx, (mut buf, len)| {\n                                buf.truncate(len);\n                                println!(\"# RECV: {} bytes\", buf.len());\n\n                                // Sends received  to the writer half.\n                                tx.send(buf).expect(\"Cannot send\");\n                                Ok(tx) as io::Result\u003c_\u003e\n                            })\n                    })\n                    .then(|r| {\n                        println!(\"# Client finished: {:?}\", r);\n                        Ok(())\n                    }));\n                Ok(())\n            })\n        }));\n    let result = executor.run_fiber(monitor).expect(\"Execution failed\");\n    println!(\"# Listener finished: {:?}\", result);\n}\n```\n\nAnd the code of the client side:\n\n```rust\n// See also: \"fibers/examples/tcp_echo_cli.rs\"\nextern crate fibers;\nextern crate futures;\nextern crate handy_async;\n\nuse fibers::{Spawn, Executor, InPlaceExecutor};\nuse fibers::net::TcpStream;\nuse futures::{Future, Stream};\nuse handy_async::io::{AsyncWrite, ReadFrom};\nuse handy_async::pattern::AllowPartial;\n\nfn main() {\n    let server_addr = \"127.0.0.1:3000\".parse().unwrap();\n\n    // `InPlaceExecutor` is suitable to execute a few fibers.\n    // It does not create any background threads,\n    // so the overhead to manage fibers is lower than `ThreadPoolExecutor`.\n    let mut executor = InPlaceExecutor::new().expect(\"Cannot create Executor\");\n    let handle = executor.handle();\n\n    // Spawns a fiber for echo client.\n    let monitor = executor.spawn_monitor(TcpStream::connect(server_addr).and_then(move |stream| {\n        println!(\"# CONNECTED: {}\", server_addr);\n        let (reader, writer) = (stream.clone(), stream);\n\n        // Writer: It sends data read from the standard input stream to the connected server.\n        let stdin_stream = vec![0; 256].allow_partial().into_stream(fibers::io::stdin());\n        handle.spawn(stdin_stream.map_err(|e| e.into_error())\n            .fold(writer, |writer, (mut buf, size)| {\n                buf.truncate(size);\n                writer.async_write_all(buf).map(|(w, _)| w).map_err(|e| e.into_error())\n            })\n            .then(|r| {\n                println!(\"# Writer finished: {:?}\", r);\n                Ok(())\n            }));\n\n        // Reader: It outputs data received from the server to the standard output stream.\n        let stream = vec![0; 256].allow_partial().into_stream(reader);\n        stream.map_err(|e| e.into_error())\n            .for_each(|(mut buf, len)| {\n                buf.truncate(len);\n                println!(\"{}\", String::from_utf8(buf).expect(\"Invalid UTF-8\"));\n                Ok(())\n            })\n    }));\n\n    // Runs until the above fiber is terminated (i.e., The TCP stream is disconnected).\n    let result = executor.run_fiber(monitor).expect(\"Execution failed\");\n    println!(\"# Disconnected: {:?}\", result);\n}\n```\n\nReal examples using `fibers`\n----------------------------\n\nHere is a list of known projects using `fibers`:\n\n- [erl_dist](https://github.com/sile/erl_dist): Erlang Distribution Protocol Implementation\n- [miasht](https://github.com/sile/miasht): Minimum Asynchronous HTTP server/client\n- [rustun](https://github.com/sile/rustun): STUN(RFC5389) server/client Implementation\n- [rusturn](https://github.com/sile/rusturn): TURN(RFC5766) server/client Implementation\n\nLicense\n-------\n\nThis library is released under the MIT License.\n\nSee the [LICENSE](LICENSE) file for full license information.\n\nCopyright (c) 2016 DWANGO Co., Ltd. All Rights Reserved.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdwango%2Ffibers-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdwango%2Ffibers-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdwango%2Ffibers-rs/lists"}