photoprism-client-go/vendor/github.com/leandro-lugaresi/hub/README.md

147 lines
5.0 KiB
Markdown
Raw Normal View History

# Hub
:incoming_envelope: A fast enough Event Hub for go applications using publish/subscribe with support patterns on topics like rabbitMQ exchanges.
[![Release](https://img.shields.io/github/release/leandro-lugaresi/hub.svg?style=flat-square)](https://github.com/leandro-lugaresi/hub/releases/latest)
[![Software License](https://img.shields.io/github/license/leandro-lugaresi/hub.svg?style=flat-square)](LICENSE.md)
[![Actions Status](https://github.com/leandro-lugaresi/hub/workflows/Go/badge.svg)](https://github.com/leandro-lugaresi/hub/actions)
[![Coverage Status](https://img.shields.io/codecov/c/github/leandro-lugaresi/hub/main.svg?style=flat-square)](https://codecov.io/gh/leandro-lugaresi/hub)
[![Go Doc](https://img.shields.io/badge/godoc-reference-blue.svg?style=flat-square)](http://godoc.org/github.com/leandro-lugaresi/hub)
[![Go Report Card](https://goreportcard.com/badge/github.com/leandro-lugaresi/hub?style=flat-square)](https://goreportcard.com/report/github.com/leandro-lugaresi/hub)
[![Say Thanks!](https://img.shields.io/badge/Say%20Thanks-!-1EAEDB.svg)](https://saythanks.io/to/leandro-lugaresi)
---
## Table of Contents
- [Install](#install)
- [Usage](#usage)
- [Examples & Demos](#examples--demos)
- [Benchmarks](#benchmarks)
- [CSTrie](#cstrie)
- [Contribute](CONTRIBUTING.md)
- [Code of conduct](CODE_OF_CONDUCT.md)
## Install
To 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.
```sh
go get -u github.com/leandro-lugaresi/hub
```
```sh
dep ensure --add github.com/leandro-lugaresi/hub
```
## Usage
### Subscribers
Hub provides subscribers as buffered (cap > `0`) and unbuffered (cap = 0) channels but we have two different types of subscribers:
- `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.
- `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.
This should be used only if loose data is acceptable. ie: metrics, logs
### Topics
This 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.
The topic must be a list of words delimited by dots (`.`) however, there is one important special case for binding keys:
`*` (star) can substitute for exactly one word.
## Examples & Demos
```go
package main
import (
"fmt"
"sync"
"github.com/leandro-lugaresi/hub"
)
func main() {
h := hub.New()
var wg sync.WaitGroup
// the cap param is used to create one buffered channel with cap = 10
// If you wan an unbuferred channel use the 0 cap
sub := h.Subscribe(10, "account.login.*", "account.changepassword.*")
wg.Add(1)
go func(s hub.Subscription) {
for msg := range s.Receiver {
fmt.Printf("receive msg with topic %s and id %d\n", msg.Name, msg.Fields["id"])
}
wg.Done()
}(sub)
h.Publish(hub.Message{
Name: "account.login.failed",
Fields: hub.Fields{"id": 123},
})
h.Publish(hub.Message{
Name: "account.changepassword.failed",
Fields: hub.Fields{"id": 456},
})
h.Publish(hub.Message{
Name: "account.login.success",
Fields: hub.Fields{"id": 123},
})
// message not routed to this subscriber
h.Publish(hub.Message{
Name: "account.foo.failed",
Fields: hub.Fields{"id": 789},
})
// close all the subscribers
h.Close()
// wait until finish all the messages on buffer
wg.Wait()
// Output:
// receive msg with topic account.login.failed and id 123
// receive msg with topic account.changepassword.failed and id 456
// receive msg with topic account.login.success and id 123
}
```
See more [here](https://godoc.org/github.com/leandro-lugaresi/hub#example-Hub)!
## Benchmarks
To run the benchmarks you can execute:
```bash
make bench
```
Currently, I only have the benchmarks of the CSTrie used internally. I will provide more benchmarks.
## Throughput
The project have one test for throughput, just execute:
```bash
make throughput
```
In a intel(R) core(TM) i5-4460 CPU @ 3.20GHz x4 we got this results:
```
go test -v -timeout 60s github.com/leandro-lugaresi/hub -run ^TestThroughput -args -throughput
=== RUN TestThroughput
1317530.091292 msg/sec
--- PASS: TestThroughput (3.04s)
PASS
ok github.com/leandro-lugaresi/hub 3.192s
```
## CSTrie
This 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)
---
This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code.
We appreciate your contribution. Please refer to our [contributing guidelines](CONTRIBUTING.md) for further information