Documentation
¶
Overview ¶
Package events provides a synchronous, in-process event bus for decoupled communication between components.
The Bus dispatches events to registered handlers in the order they were subscribed. Publishing is synchronous — Publish returns only after every handler has run (or the first one returns an error).
Defining events ¶
Each event is a small, immutable type that implements Event by returning a stable string key:
type OrderPlacedEvent struct {
OrderID string
Total int64
}
func (e OrderPlacedEvent) EventType() string { return "order.placed" }
Publishing ¶
Services hold a Publisher (or the concrete *Bus) and call Publish after the primary operation succeeds:
_ = s.publisher.Publish(ctx, OrderPlacedEvent{
OrderID: order.ID,
Total: order.Total,
})
Use _ = to swallow the error when handler failures must not abort the primary operation. Return the error when cleanup is a hard requirement.
Subscribing ¶
Register handlers against the shared Bus during startup:
bus.Subscribe("order.placed", func(ctx context.Context, e events.Event) error {
evt := e.(OrderPlacedEvent)
return invoicing.CreateDraft(ctx, evt.OrderID, evt.Total)
})
Testing ¶
Pass NoopPublisher when a component needs a Publisher but the test doesn't care about events, and FakePublisher to assert which events were published:
pub := events.NewFakePublisher()
svc := NewOrderService(pub)
_ = svc.Place(ctx, order)
assert.Equal(t, []events.Event{
OrderPlacedEvent{OrderID: order.ID, Total: order.Total},
}, pub.Published())
Swapping the implementation ¶
Code should depend on the Publisher interface rather than *Bus directly. This allows swapping to a distributed broker (e.g. NATS, Kafka) by providing a different implementation at the wiring layer without touching the rest of the codebase.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Bus ¶
type Bus struct {
// contains filtered or unexported fields
}
Bus is a synchronous, in-process event bus.
type FakePublisher ¶
type FakePublisher struct {
// contains filtered or unexported fields
}
FakePublisher records every published event instead of dispatching it. Use it in tests to assert which events a service published, without wiring a Bus and handlers. Safe for concurrent use.
func NewFakePublisher ¶
func NewFakePublisher() *FakePublisher
NewFakePublisher creates an empty FakePublisher.
func (*FakePublisher) Publish ¶
func (p *FakePublisher) Publish(_ context.Context, event Event) error
Publish records event and returns nil.
func (*FakePublisher) Published ¶
func (p *FakePublisher) Published() []Event
Published returns a copy of every event recorded so far, in publish order.
type NoopPublisher ¶
type NoopPublisher struct{}
NoopPublisher discards every event. Use it as a default Publisher when events are disabled or irrelevant to the code under test.
func NewNoopPublisher ¶
func NewNoopPublisher() NoopPublisher
NewNoopPublisher returns a ready-to-use NoopPublisher.
type Publisher ¶
Publisher is responsible for publishing events to subscribers. Implementations can be in-process (like the provided Bus) or distributed (e.g., using a message broker).
type Subscriber ¶
Subscriber allows registration of handlers for specific event types.