Added performant in-process message broker to data's routing subpackage
This commit is contained in:
56
pkg/data/routing/broker.go
Normal file
56
pkg/data/routing/broker.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package routing
|
||||
|
||||
import "sync"
|
||||
|
||||
const DefaultRingCapacity = 1 << 8 // Best if power of 2 (or so I am told)
|
||||
|
||||
// Broker manages topics and issues publisher/subscriber handles.
|
||||
type Broker struct {
|
||||
mu sync.RWMutex
|
||||
topics map[string]*TopicRing
|
||||
}
|
||||
|
||||
func NewBroker() *Broker {
|
||||
return &Broker{
|
||||
topics: make(map[string]*TopicRing),
|
||||
}
|
||||
}
|
||||
|
||||
// getOrCreateRing handles the race condition where a subscriber might attach
|
||||
// to a topic before the publisher has created it, and vice versa.
|
||||
// This is because we allow either a publisher or a subscriber to 'create' the topic
|
||||
func (b *Broker) getOrCreateRing(topicKey string, requestedCap int) *TopicRing {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
|
||||
ring, exists := b.topics[topicKey]
|
||||
if !exists {
|
||||
cap := requestedCap
|
||||
if cap <= 0 {
|
||||
cap = DefaultRingCapacity
|
||||
}
|
||||
ring = newTopicRing(cap)
|
||||
b.topics[topicKey] = ring
|
||||
}
|
||||
return ring
|
||||
}
|
||||
|
||||
// RegisterPublisher returns a fast-path Publisher.
|
||||
func (b *Broker) RegisterPublisher(topicKey string, capacity int) Publisher {
|
||||
ring := b.getOrCreateRing(topicKey, capacity)
|
||||
return &ringPublisher{
|
||||
ring: ring,
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterSubscriber attaches a consumer to a topic and returns a fast-path Subscriber.
|
||||
// We don't allow subscribrs to specify a buffer capacity size.
|
||||
// As a general rule, a publisher takes precedence over a subscriber
|
||||
func (b *Broker) RegisterSubscriber(topicKey string) Subscriber {
|
||||
ring := b.getOrCreateRing(topicKey, 0)
|
||||
consumer := ring.addConsumer()
|
||||
return &ringSubscriber{
|
||||
ring: ring,
|
||||
consumer: consumer,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user