{"id":24991959,"url":"https://github.com/rubik/orizuru","last_synced_at":"2026-02-26T02:31:47.669Z","repository":{"id":57650403,"uuid":"213203467","full_name":"rubik/orizuru","owner":"rubik","description":"A reliable, scalable and flexible Redis message queue for Rust.","archived":false,"fork":false,"pushed_at":"2019-10-13T06:40:13.000Z","size":261,"stargazers_count":16,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-17T19:51:52.151Z","etag":null,"topics":["job-queue","message-queue","redis","redis-queue"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rubik.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":"2019-10-06T16:31:32.000Z","updated_at":"2025-03-04T11:35:56.000Z","dependencies_parsed_at":"2022-09-26T20:22:13.887Z","dependency_job_id":null,"html_url":"https://github.com/rubik/orizuru","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/rubik/orizuru","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubik%2Forizuru","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubik%2Forizuru/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubik%2Forizuru/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubik%2Forizuru/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rubik","download_url":"https://codeload.github.com/rubik/orizuru/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rubik%2Forizuru/sbom","scorecard":{"id":788801,"data":{"date":"2025-08-11","repo":{"name":"github.com/rubik/orizuru","commit":"26c8bc7009a7da0f84b0653a2d4685b5fe77c475"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"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":"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":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","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":"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":"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":"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":"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":"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: ISC 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"}}]},"last_synced_at":"2025-08-23T06:51:59.876Z","repository_id":57650403,"created_at":"2025-08-23T06:51:59.876Z","updated_at":"2025-08-23T06:51:59.876Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279014546,"owners_count":26085536,"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","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"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":["job-queue","message-queue","redis","redis-queue"],"created_at":"2025-02-04T13:53:13.889Z","updated_at":"2025-10-13T09:36:29.264Z","avatar_url":"https://github.com/rubik.png","language":"Rust","readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg alt=\"Orizuru logo\" src=\"https://github.com/rubik/orizuru/raw/master/images/logo.png\" height=\"130\" /\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003eOrizuru (折鶴)\u003c/h1\u003e\n  \u003cp\u003eA reliable, scalable and flexible Redis message queue for Rust.\u003c/p\u003e\n  \u003ca href=\"https://travis-ci.org/rubik/orizuru\"\u003e\n    \u003cimg src=\"https://img.shields.io/travis/rubik/orizuru?style=for-the-badge\" alt=\"Build\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://coveralls.io/github/rubik/orizuru\"\u003e\n    \u003cimg src=\"https://img.shields.io/coveralls/github/rubik/orizuru?style=for-the-badge\" alt=\"Code Coverage\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://crates.io/crates/orizuru\"\u003e\n   \u003cimg src=\"https://img.shields.io/crates/d/orizuru?style=for-the-badge\" alt=\"Downloads (all time)\"\u003e\n  \u003ca\u003e\n  \u003ca href=\"https://github.com/rubik/orizuru/blob/master/LICENSE\"\u003e\n    \u003cimg src=\"https://img.shields.io/crates/l/orizuru?style=for-the-badge\" alt=\"ISC License\"\u003e\n  \u003c/a\u003e\n  \u003cbr\u003e\n  \u003cbr\u003e\n\u003c/div\u003e\n\n\n# Design\nQueues are backed by Redis lists and as such they support multiple producers\nand consumers:\n\n* To publish a message to a **source** queue, a producer runs an\n  [`LPUSH`](https://redis.io/commands/lpush) command;\n* Periodically, a consumer fetches messages from the *source* queue and pushes\n  them to its own **processing** queue. Then, it may choose to acknowledge them\n  or reject them. Acknowledged messages are removed from the *processing*\n  queue, while rejected messages are moved to the **unack** queue.\n\nEach queue can have an unlimited number of concurrent consumers. Consumers\nfetch messages with the [`BRPOPLPUSH`](https://redis.io/commands/brpoplpush)\ncommand, that blocks until at least one message is available on the source\nqueue, and then pushes it to its processing queue. This operation is atomic,\nwhich means that only one consumer can receive the message even if there are\nmultiple consumers fetching messages from the *source* queue.\n\nOptionally, unacknowledged messages can be collected by the garbage collector\nthat periodically returns them to the source queue. If the garbage collector\ndoes not run, *unack* queues are essentially dead-letter queues and could grow\nwithout bound.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"Orizuru architecture\" src=\"https://github.com/rubik/orizuru/raw/master/images/architecture.png\" height=\"470\" /\u003e\n\u003c/p\u003e\n\n## Simplicity\nIn line with Rust's philosophy of not not picking a specific implementation\nstrategy, Orizuru is designed with simplicity in mind. This informs both the\npublic API, which is minimal, and the implementation. All the functionality is\nimplemented as a library, so that the user is free to integrate it in their\narchitecture however they wish.\n\n## API\n\n`Producer::push\u003cT: MessageEncodable\u003e(message: T) -\u003e Option\u003cRedisResult\u003ci32\u003e\u003e`\u003cbr/\u003e\n    Push a message onto a *source* queue.\n\n`Consumer::next\u003cT: MessageDecodable\u003e() -\u003e Option\u003cRedisResult\u003cMessageGuard\u003cT\u003e\u003e\u003e`\u003cbr/\u003e\n    Fetch the next message from the queue. This method blocks and waits until a\n    new message is available.\n\n`MessageGuard::ack() -\u003e RedisResult\u003cValue\u003e`\u003cbr/\u003e\n    Acknowledge the message and remove it from the *processing* queue.\n\n`MessageGuard::reject() -\u003e RedisResult\u003cValue\u003e`\u003cbr/\u003e\n    Reject the message and push it from the *processing* queue to the *unack*\n    queue.\n\n`MessageGuard::push(push_queue_name: String) -\u003e RedisResult\u003cValue\u003e`\u003cbr/\u003e\n    Remove the message from the processing queue and push it to the specified\n    queue. It can be used to implement retries.\n\nThe traits `MessageEncodable` and `MessageDecodable` ensure that the message\ncan be serialized and deserialized to/from Redis. They are implemented by\ndefault for all the objects that implements the `Serialize` and `Deserialized`\ntraits from the serde crate, by using the [Msgpack](https://msgpack.org/)\nencoding. This is a binary encoding analogous to JSON. It was chosen because\nof the encoding and decoding speed and space efficiency over JSON.\n\n# Usage patterns\nOrizuru is a message queue, but it can be specialized into a *job* queue, when\nthe messages represent job payloads. However, the acknowledgement pattern\ndiffers between the two. In the case of a generic message queue, messages are\nacknowledged as soon as they are received, as that is what matters. In the case\nof a job queue, on the other hand, messages are acknowledged after the job has\nbeen executed (maybe even successfully). That protects the jobs from random\nfailures or worker crashes. In both cases the presence of a garbage collector\nis essential to ensure that the deliveries/executions are retried.\n\n# License\n\nISC\n\n\u003cp align=\"center\"\u003e\u003csub\u003eLogo image based on the one made by \u003ca href=\"https://www.flaticon.com/authors/smashicons\" title=\"Smashicons\"\u003eSmashicons\u003c/a\u003e for \u003ca href=\"https://www.flaticon.com/\" title=\"Flaticon\"\u003ewww.flaticon.com\u003c/a\u003e.\u003c/p\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubik%2Forizuru","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frubik%2Forizuru","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frubik%2Forizuru/lists"}