Changeset 0.23.1 (#154)
This commit is contained in:
@@ -10,9 +10,10 @@ import (
|
||||
// Handlers subscribe to patterns (exact or trailing wildcard).
|
||||
// Publishing fans out to all matching subscribers.
|
||||
type Bus struct {
|
||||
mu sync.RWMutex
|
||||
subs map[string][]*subscription
|
||||
seq uint64 // subscription ID counter
|
||||
mu sync.RWMutex
|
||||
subs map[string][]*subscription
|
||||
seq uint64 // subscription ID counter
|
||||
broadcastHook func(Event) // called after Publish for cross-pod fan-out; nil-safe
|
||||
}
|
||||
|
||||
type subscription struct {
|
||||
@@ -28,6 +29,15 @@ func NewBus() *Bus {
|
||||
}
|
||||
}
|
||||
|
||||
// SetBroadcastHook registers a function called after every Publish.
|
||||
// Used by the Postgres LISTEN/NOTIFY adapter to fan out across pods.
|
||||
// The hook is NOT called by publishLocal (avoids re-broadcast loops).
|
||||
func (b *Bus) SetBroadcastHook(fn func(Event)) {
|
||||
b.mu.Lock()
|
||||
b.broadcastHook = fn
|
||||
b.mu.Unlock()
|
||||
}
|
||||
|
||||
// Subscribe registers a handler for a label pattern.
|
||||
// Returns an unsubscribe function.
|
||||
//
|
||||
@@ -60,7 +70,22 @@ func (b *Bus) Subscribe(pattern string, handler Handler) func() {
|
||||
// Publish dispatches an event to all matching subscribers.
|
||||
// Handlers are called synchronously in subscription order.
|
||||
// Use PublishAsync for non-blocking dispatch.
|
||||
// After local dispatch, calls the broadcastHook if set (Postgres fan-out).
|
||||
func (b *Bus) Publish(event Event) {
|
||||
b.publishLocal(event)
|
||||
|
||||
b.mu.RLock()
|
||||
hook := b.broadcastHook
|
||||
b.mu.RUnlock()
|
||||
if hook != nil {
|
||||
hook(event)
|
||||
}
|
||||
}
|
||||
|
||||
// publishLocal dispatches to local subscribers only, without triggering
|
||||
// the broadcastHook. Used by the Postgres listener to re-publish remote
|
||||
// events without causing an infinite re-broadcast loop.
|
||||
func (b *Bus) publishLocal(event Event) {
|
||||
b.mu.RLock()
|
||||
var matched []Handler
|
||||
for pattern, subs := range b.subs {
|
||||
@@ -79,6 +104,7 @@ func (b *Bus) Publish(event Event) {
|
||||
|
||||
// PublishAsync dispatches an event to all matching subscribers
|
||||
// in separate goroutines. Useful for I/O-heavy handlers.
|
||||
// Also calls the broadcastHook asynchronously if set.
|
||||
func (b *Bus) PublishAsync(event Event) {
|
||||
b.mu.RLock()
|
||||
var matched []Handler
|
||||
@@ -89,11 +115,15 @@ func (b *Bus) PublishAsync(event Event) {
|
||||
}
|
||||
}
|
||||
}
|
||||
hook := b.broadcastHook
|
||||
b.mu.RUnlock()
|
||||
|
||||
for _, h := range matched {
|
||||
go h(event)
|
||||
}
|
||||
if hook != nil {
|
||||
go hook(event)
|
||||
}
|
||||
}
|
||||
|
||||
// match checks if a concrete label matches a subscription pattern.
|
||||
|
||||
Reference in New Issue
Block a user