tendermint: github.com/tendermint/tendermint/libs/pubsub Index | Files | Directories

package pubsub

import "github.com/tendermint/tendermint/libs/pubsub"

Package pubsub implements a pub-sub model with a single publisher (Server) and multiple subscribers (clients).

Though you can have multiple publishers by sharing a pointer to a server or by giving the same channel to each publisher and publishing messages from that channel (fan-in).

Clients subscribe for messages, which could be of any type, using a query. When some message is published, we match it with all queries. If there is a match, this message will be pushed to all clients, subscribed to that query. See query subpackage for our implementation.


q, err := query.New("account.name='John'")
if err != nil {
    return err
ctx, cancel := context.WithTimeout(context.Background(), 1 * time.Second)
defer cancel()
subscription, err := pubsub.Subscribe(ctx, "johns-transactions", q)
if err != nil {
    return err

for {
    select {
    case msg <- subscription.Out():
        // handle msg.Data() and msg.Events()
    case <-subscription.Cancelled():
        return subscription.Err()


Package Files

pubsub.go subscription.go


var (
    // ErrSubscriptionNotFound is returned when a client tries to unsubscribe
    // from not existing subscription.
    ErrSubscriptionNotFound = errors.New("subscription not found")

    // ErrAlreadySubscribed is returned when a client tries to subscribe twice or
    // more using the same query.
    ErrAlreadySubscribed = errors.New("already subscribed")
var (
    // ErrUnsubscribed is returned by Err when a client unsubscribes.
    ErrUnsubscribed = errors.New("client unsubscribed")

    // ErrOutOfCapacity is returned by Err when a client is not pulling messages
    // fast enough. Note the client's subscription will be terminated.
    ErrOutOfCapacity = errors.New("client is not pulling messages fast enough")

type Message Uses

type Message struct {
    // contains filtered or unexported fields

Message glues data and events together.

func NewMessage Uses

func NewMessage(data interface{}, events map[string][]string) Message

func (Message) Data Uses

func (msg Message) Data() interface{}

Data returns an original data published.

func (Message) Events Uses

func (msg Message) Events() map[string][]string

Events returns events, which matched the client's query.

type Option Uses

type Option func(*Server)

Option sets a parameter for the server.

func BufferCapacity Uses

func BufferCapacity(cap int) Option

BufferCapacity allows you to specify capacity for the internal server's queue. Since the server, given Y subscribers, could only process X messages, this option could be used to survive spikes (e.g. high amount of transactions during peak hours).

type Query Uses

type Query interface {
    Matches(events map[string][]string) (bool, error)
    String() string

Query defines an interface for a query to be used for subscribing. A query matches against a map of events. Each key in this map is a composite of the even type and an attribute key (e.g. "{eventType}.{eventAttrKey}") and the values are the event values that are contained under that relationship. This allows event types to repeat themselves with the same set of keys and different values.

type Server Uses

type Server struct {
    // contains filtered or unexported fields

Server allows clients to subscribe/unsubscribe for messages, publishing messages with or without events, and manages internal state.

func NewServer Uses

func NewServer(options ...Option) *Server

NewServer returns a new server. See the commentary on the Option functions for a detailed description of how to configure buffering. If no options are provided, the resulting server's queue is unbuffered.

func (*Server) BufferCapacity Uses

func (s *Server) BufferCapacity() int

BufferCapacity returns capacity of the internal server's queue.

func (*Server) NumClientSubscriptions Uses

func (s *Server) NumClientSubscriptions(clientID string) int

NumClientSubscriptions returns the number of subscriptions the client has.

func (*Server) NumClients Uses

func (s *Server) NumClients() int

NumClients returns the number of clients.

func (*Server) OnReset Uses

func (s *Server) OnReset() error

OnReset implements Service.OnReset

func (*Server) OnStart Uses

func (s *Server) OnStart() error

OnStart implements Service.OnStart by starting the server.

func (*Server) OnStop Uses

func (s *Server) OnStop()

OnStop implements Service.OnStop by shutting down the server.

func (*Server) Publish Uses

func (s *Server) Publish(ctx context.Context, msg interface{}) error

Publish publishes the given message. An error will be returned to the caller if the context is canceled.

func (*Server) PublishWithEvents Uses

func (s *Server) PublishWithEvents(ctx context.Context, msg interface{}, events map[string][]string) error

PublishWithEvents publishes the given message with the set of events. The set is matched with clients queries. If there is a match, the message is sent to the client.

func (*Server) Subscribe Uses

func (s *Server) Subscribe(
    ctx context.Context,
    clientID string,
    query Query,
    outCapacity ...int) (*Subscription, error)

Subscribe creates a subscription for the given client.

An error will be returned to the caller if the context is canceled or if subscription already exist for pair clientID and query.

outCapacity can be used to set a capacity for Subscription#Out channel (1 by default). Panics if outCapacity is less than or equal to zero. If you want an unbuffered channel, use SubscribeUnbuffered.

func (*Server) SubscribeUnbuffered Uses

func (s *Server) SubscribeUnbuffered(ctx context.Context, clientID string, query Query) (*Subscription, error)

SubscribeUnbuffered does the same as Subscribe, except it returns a subscription with unbuffered channel. Use with caution as it can freeze the server.

func (*Server) Unsubscribe Uses

func (s *Server) Unsubscribe(ctx context.Context, clientID string, query Query) error

Unsubscribe removes the subscription on the given query. An error will be returned to the caller if the context is canceled or if subscription does not exist.

func (*Server) UnsubscribeAll Uses

func (s *Server) UnsubscribeAll(ctx context.Context, clientID string) error

UnsubscribeAll removes all client subscriptions. An error will be returned to the caller if the context is canceled or if subscription does not exist.

type Subscription Uses

type Subscription struct {
    // contains filtered or unexported fields

A Subscription represents a client subscription for a particular query and consists of three things: 1) channel onto which messages and events are published 2) channel which is closed if a client is too slow or choose to unsubscribe 3) err indicating the reason for (2)

func NewSubscription Uses

func NewSubscription(outCapacity int) *Subscription

NewSubscription returns a new subscription with the given outCapacity.

func (*Subscription) Cancelled Uses

func (s *Subscription) Cancelled() <-chan struct{}

Cancelled returns a channel that's closed when the subscription is terminated and supposed to be used in a select statement.

func (*Subscription) Err Uses

func (s *Subscription) Err() error

Err returns nil if the channel returned by Cancelled is not yet closed. If the channel is closed, Err returns a non-nil error explaining why:

- ErrUnsubscribed if the subscriber choose to unsubscribe,
- ErrOutOfCapacity if the subscriber is not pulling messages fast enough
and the channel returned by Out became full,

After Err returns a non-nil error, successive calls to Err return the same error.

func (*Subscription) Out Uses

func (s *Subscription) Out() <-chan Message

Out returns a channel onto which messages and events are published. Unsubscribe/UnsubscribeAll does not close the channel to avoid clients from receiving a nil message.


queryPackage query provides a parser for a custom query format:

Package pubsub imports 5 packages (graph) and is imported by 54 packages. Updated 2020-10-14. Refresh now. Tools for package owners.