pubsub is a very small library for implementing the simplest possible publish-subscribe mechanism for Go using channels.
import "github.com/borud/broker"
broker := New(Config{
DownStreamChanLen: 100,
PublishChanLen: 100,
SubscribeChanLen: 10,
UnsubscribeChanLen: 10,
DeliveryTimeout: 10*time.Millisecond,
})
The configuration options are
-
DownStreamChanLen
is the length of the channel used to send messages to the subscriber. -
PublishChanLen
is the length of the incoming channel used byPublish()
-
SubscribeChanLen
is the length of the channel that acceptsSubscribe()
requests -
UnsubscribeChanLen
is the length of the channel that accepts unsubscribe requests. -
DeliveryTimeout
is the timeout before giving up delivering a message to a subscriber
sub, err := broker.Subscribe("/foo/bar")
for msg := range sub.Messages() {
log.Printf("topic = '%s', message = '%+v'", msg.Topic, msg.Payload)
}
err := broker.Publish("/foo", "some payload", 300 * time.Millisecond)
err := sub.Cancel()
broker.Shutdown()
Topics are entirely dynamic, meaning that a topic exists if there are subscribers listening to it. If a message is published to a topic that has no subscribers, nothing will happen and the message is silently discarded.
Topics are hierarchical and look like filesyste paths and matching is by path prefix.
/house/bedroom/light
/house/bedroom/temp
/house/kitchen/light
/house/kitchen/temp
/house/kitchen/humidity
Your subscription can be for any prefix of the path, including the
full path. You will receive all messages that match your prefix. So
for instance if you subscribe to /house/kitchen
you will get all
messages sent to
/house/kitchen
/house/kitchen/light
/house/kitchen/temp
/house/kitchen/humidity
If you subscribe to /house/kitchen/temp
you will only get messages
sent to this single topic since it has no children.
At this time no wildcard matching is supported.
Libraries shouldn't emit log messages, but sometimes you might want to output log messages if you suspect something funny is going on. You can register your own logger via the Config
type, like this:
b := New(Config{Logger: log.Printf})
The Logger
is of type Printfer
(a Printf'er to use the naming conventions of go), which looks like this:
func(string, ...interface{})
...which happens to be the signature of log.Printf
(but not fmt.Printf
).