{"id":13413409,"url":"https://github.com/leandro-lugaresi/hub","last_synced_at":"2026-01-17T06:54:01.223Z","repository":{"id":56673343,"uuid":"129464544","full_name":"leandro-lugaresi/hub","owner":"leandro-lugaresi","description":":incoming_envelope: A fast Message/Event Hub using publish/subscribe pattern with support for topics like* rabbitMQ exchanges for Go applications","archived":false,"fork":false,"pushed_at":"2020-10-26T14:23:55.000Z","size":81,"stargazers_count":145,"open_issues_count":2,"forks_count":18,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-07-31T20:52:18.609Z","etag":null,"topics":["eventbus","go","golang","hacktoberfest","message-bus","pubsub","topic"],"latest_commit_sha":null,"homepage":"","language":"Go","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/leandro-lugaresi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-13T23:47:13.000Z","updated_at":"2024-07-26T23:53:39.000Z","dependencies_parsed_at":"2022-08-15T23:00:57.491Z","dependency_job_id":null,"html_url":"https://github.com/leandro-lugaresi/hub","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/leandro-lugaresi/hub","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandro-lugaresi%2Fhub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandro-lugaresi%2Fhub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandro-lugaresi%2Fhub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandro-lugaresi%2Fhub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leandro-lugaresi","download_url":"https://codeload.github.com/leandro-lugaresi/hub/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandro-lugaresi%2Fhub/sbom","scorecard":{"id":581845,"data":{"date":"2025-08-11","repo":{"name":"github.com/leandro-lugaresi/hub","commit":"99dcacb0e1043e8d8660485736855d0ddd3980e6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"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":"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":"Code-Review","score":0,"reason":"Found 0/22 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":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: no topLevel permission defined: .github/workflows/pull_request.yml:1","Info: no jobLevel write permissions found"],"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":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:9: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/ci.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pull_request.yml:9: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/pull_request.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pull_request.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/pull_request.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pull_request.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/pull_request.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pull_request.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/pull_request.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pull_request.yml:38: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/pull_request.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pull_request.yml:40: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/pull_request.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pull_request.yml:52: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/pull_request.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pull_request.yml:53: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/pull_request.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pull_request.yml:64: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/pull_request.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pull_request.yml:65: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/pull_request.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pull_request.yml:75: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/pull_request.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pull_request.yml:76: update your workflow using https://app.stepsecurity.io/secureworkflow/leandro-lugaresi/hub/pull_request.yml/main?enable=pin","Info:   0 out of   8 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   7 third-party GitHubAction dependencies pinned"],"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":"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":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: 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":"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":"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":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"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":"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":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 21 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-20T19:22:45.810Z","repository_id":56673343,"created_at":"2025-08-20T19:22:45.810Z","updated_at":"2025-08-20T19:22:45.810Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28502972,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T04:31:57.058Z","status":"ssl_error","status_checked_at":"2026-01-17T04:31:45.816Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["eventbus","go","golang","hacktoberfest","message-bus","pubsub","topic"],"created_at":"2024-07-30T20:01:39.686Z","updated_at":"2026-01-17T06:54:01.191Z","avatar_url":"https://github.com/leandro-lugaresi.png","language":"Go","funding_links":[],"categories":["Messaging","消息","消息传递","消息系统","机器学习","Relational Databases"],"sub_categories":["Advanced Console UIs","Search and Analytic Databases","检索及分析资料库","交流","SQL 查询语句构建库"],"readme":"# Hub\n\n:incoming_envelope: A fast enough Event Hub for go applications using publish/subscribe with support patterns on topics like rabbitMQ exchanges.\n\n[![Release](https://img.shields.io/github/release/leandro-lugaresi/hub.svg?style=flat-square)](https://github.com/leandro-lugaresi/hub/releases/latest)\n[![Software License](https://img.shields.io/github/license/leandro-lugaresi/hub.svg?style=flat-square)](LICENSE.md)\n[![Actions Status](https://github.com/leandro-lugaresi/hub/workflows/Go/badge.svg)](https://github.com/leandro-lugaresi/hub/actions)\n[![Coverage Status](https://img.shields.io/codecov/c/github/leandro-lugaresi/hub/main.svg?style=flat-square)](https://codecov.io/gh/leandro-lugaresi/hub)\n[![Go Doc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/leandro-lugaresi/hub)\n[![Go Report Card](https://goreportcard.com/badge/github.com/leandro-lugaresi/hub?style=flat-square)](https://goreportcard.com/report/github.com/leandro-lugaresi/hub)\n[![Say Thanks!](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/leandro-lugaresi)\n\n---\n\n## Table of Contents\n\n- [Install](#install)\n- [Usage](#usage)\n- [Examples \u0026 Demos](#examples--demos)\n- [Benchmarks](#benchmarks)\n- [CSTrie](#cstrie)\n- [Contribute](CONTRIBUTING.md)\n- [Code of conduct](CODE_OF_CONDUCT.md)\n\n## Install\n\nTo install this library you can `go get` it but I encourage you to always vendor your dependencies or use one of the version tags of this project.\n\n```sh\ngo get -u github.com/leandro-lugaresi/hub\n```\n\n```sh\ndep ensure --add github.com/leandro-lugaresi/hub\n```\n\n## Usage\n\n### Subscribers\n\nHub provides subscribers as buffered (cap \u003e `0`) and unbuffered (cap = 0) channels but we have two different types of subscribers:\n\n- `Subscriber` this is the default subscriber and it's a blocking subscriber so if the channel is full and you try to send another message the send operation will block until the subscriber consumes some message.\n- `NonBlockingSubscriber` this subscriber will never block on the publish side but if the capacity of the channel is reached the publish operation will be lost and an alert will be trigged.\n  This should be used only if loose data is acceptable. ie: metrics, logs\n\n### Topics\n\nThis library uses the same concept of topic exchanges on rabbiMQ, so the message name is used to find all the subscribers that match the topic, like a route.\nThe topic must be a list of words delimited by dots (`.`) however, there is one important special case for binding keys:\n`*` (star) can substitute for exactly one word.\n\n## Examples \u0026 Demos\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"sync\"\n\n\t\"github.com/leandro-lugaresi/hub\"\n)\nfunc main() {\n\th := hub.New()\n\tvar wg sync.WaitGroup\n\t// the cap param is used to create one buffered channel with cap = 10\n\t// If you wan an unbuferred channel use the 0 cap\n\tsub := h.Subscribe(10, \"account.login.*\", \"account.changepassword.*\")\n\twg.Add(1)\n\tgo func(s hub.Subscription) {\n\t\tfor msg := range s.Receiver {\n\t\t\tfmt.Printf(\"receive msg with topic %s and id %d\\n\", msg.Name, msg.Fields[\"id\"])\n\t\t}\n\t\twg.Done()\n\t}(sub)\n\n\th.Publish(hub.Message{\n\t\tName:   \"account.login.failed\",\n\t\tFields: hub.Fields{\"id\": 123},\n\t})\n\th.Publish(hub.Message{\n\t\tName:   \"account.changepassword.failed\",\n\t\tFields: hub.Fields{\"id\": 456},\n\t})\n\th.Publish(hub.Message{\n\t\tName:   \"account.login.success\",\n\t\tFields: hub.Fields{\"id\": 123},\n\t})\n\t// message not routed to this subscriber\n\th.Publish(hub.Message{\n\t\tName:   \"account.foo.failed\",\n\t\tFields: hub.Fields{\"id\": 789},\n\t})\n\n\t// close all the subscribers\n\th.Close()\n\t// wait until finish all the messages on buffer\n\twg.Wait()\n\n\t// Output:\n\t// receive msg with topic account.login.failed and id 123\n\t// receive msg with topic account.changepassword.failed and id 456\n\t// receive msg with topic account.login.success and id 123\n}\n```\n\nSee more [here](https://godoc.org/github.com/leandro-lugaresi/hub#example-Hub)!\n\n## Benchmarks\n\nTo run the benchmarks you can execute:\n\n```bash\nmake bench\n```\n\nCurrently, I only have the benchmarks of the CSTrie used internally. I will provide more benchmarks.\n\n## Throughput\n\nThe project have one test for throughput, just execute:\n\n```bash\nmake throughput\n```\n\nIn a intel(R) core(TM) i5-4460 CPU @ 3.20GHz x4 we got this results:\n\n```\ngo test -v -timeout 60s github.com/leandro-lugaresi/hub -run ^TestThroughput -args -throughput\n=== RUN   TestThroughput\n1317530.091292 msg/sec\n--- PASS: TestThroughput (3.04s)\nPASS\nok      github.com/leandro-lugaresi/hub 3.192s\n```\n\n## CSTrie\n\nThis project uses internally an awesome Concurrent Subscription Trie done by [@tylertreat](https://github.com/tylertreat). If you want to learn more about see this [blog post](http://bravenewgeek.com/fast-topic-matching/) and the code is [here](https://github.com/tylertreat/fast-topic-matching)\n\n---\n\nThis project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.\nWe appreciate your contribution. Please refer to our [contributing guidelines](CONTRIBUTING.md) for further information\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleandro-lugaresi%2Fhub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleandro-lugaresi%2Fhub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleandro-lugaresi%2Fhub/lists"}