Help us shape the future of Go! Take the 2026 Go Developer Survey

events

package
v0.35.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 1, 2026 License: MIT Imports: 13 Imported by: 1

Documentation

Overview

Package events dispatches typed events to listeners registered by type. Listeners are plain functions; registration is explicit code (no discovery):

type UserRegistered struct{ User models.User }

bus.Register(events.On(listeners.SendWelcome)) // func(ctx, UserRegistered) error
err := bus.Dispatch(ctx, UserRegistered{User: u})

Async listeners run on a bounded goroutine pool that Shutdown drains. Queued listeners (OnQueued) run as queue jobs, so they survive restarts and are retried. Apps get a Bus in app.Events; Fake records dispatched events in tests.

See https://github.com/AlexGalhardo/vukem/blob/main/docs/subsystems.md#events.

Example
package main

import (
	"context"
	"fmt"
	"log/slog"

	"github.com/AlexGalhardo/vukem/events"
)

type UserRegistered struct{ Email string }

func main() {
	ctx := context.Background()
	bus := events.New(slog.New(slog.DiscardHandler), 4)
	defer func() { _ = bus.Shutdown(ctx) }()

	bus.Register(events.On(func(_ context.Context, e UserRegistered) error {
		fmt.Println("welcome mail to", e.Email)
		return nil
	}))

	err := bus.Dispatch(ctx, UserRegistered{Email: "ada@example.com"})
	fmt.Println(err)
}
Output:
welcome mail to ada@example.com
<nil>

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrClosed = errors.New("events: bus is shut down")

ErrClosed is returned by Dispatch after Shutdown.

View Source
var ErrNoQueue = errors.New("events: queued listener needs a queue (Bus.SetQueue)")

ErrNoQueue is returned when a queued listener runs on a bus without a queue.

Functions

func Dispatched

func Dispatched[E any](f *Fake) []E

Dispatched returns the recorded events of type E.

func Listen

func Listen[E any](b *Bus, fn func(ctx context.Context, e E) error)

Listen registers a synchronous listener for E.

func ListenAsync

func ListenAsync[E any](b *Bus, fn func(ctx context.Context, e E) error)

ListenAsync registers an async listener for E.

Types

type Bus

type Bus struct {
	// contains filtered or unexported fields
}

Bus holds listeners and runs them.

func New

func New(log *slog.Logger, workers int) *Bus

New returns a bus running at most workers async listeners at once (0 = 16).

func (*Bus) Dispatch

func (b *Bus) Dispatch(ctx context.Context, event any) error

Dispatch runs the synchronous listeners of event's type in registration order (stopping at the first error) and schedules the async ones. Events without listeners are fine.

func (*Bus) Jobs added in v0.16.0

func (b *Bus) Jobs() []queue.Registration

Jobs returns the queue handlers of the queued listeners, to register on the queue.

func (*Bus) RecordTo added in v0.28.0

func (b *Bus) RecordTo(f *Fake)

RecordTo makes Dispatch record every event in f instead of running the listeners (sync, async and queued), for tests that assert what was dispatched; read them with Dispatched. RecordTo(nil) restores normal dispatch.

func (*Bus) Register

func (b *Bus) Register(regs ...Registration)

Register adds listeners in order.

func (*Bus) SetObserver added in v0.19.0

func (b *Bus) SetObserver(obs Observer)

SetObserver reports dispatches to obs (development tooling such as devtools).

func (*Bus) SetQueue added in v0.16.0

func (b *Bus) SetQueue(fn func() (Enqueuer, error))

SetQueue sets how queued listeners reach the queue (called lazily on the first queued dispatch).

func (*Bus) Shutdown

func (b *Bus) Shutdown(ctx context.Context) error

Shutdown stops accepting events and waits for async listeners until ctx is done.

type Dispatcher

type Dispatcher interface {
	Dispatch(ctx context.Context, event any) error
}

Dispatcher dispatches events (Bus and Fake implement it).

type Enqueuer added in v0.16.0

type Enqueuer interface {
	DispatchKind(ctx context.Context, kind string, payload any, opts ...queue.Option) error
}

Enqueuer sends events to queued listeners (*queue.Queue implements it).

type Event added in v0.19.0

type Event struct {
	// Type is the event's Go type ("main.UserRegistered").
	Type string
	// Listeners is the number of listeners (sync, async and queued).
	Listeners int
	// Duration covers the synchronous listeners and enqueueing.
	Duration time.Duration
	// Err is the error Dispatch returned.
	Err error
}

Event describes one Bus.Dispatch for an Observer. It carries the event's Go type only, never its fields (they may hold user data).

type Fake

type Fake struct {
	// contains filtered or unexported fields
}

Fake records dispatched events instead of running listeners (tests).

Example
package main

import (
	"context"
	"fmt"

	"github.com/AlexGalhardo/vukem/events"
)

type UserRegistered struct{ Email string }

func main() {
	fake := events.NewFake()

	_ = fake.Dispatch(context.Background(), UserRegistered{Email: "ada@example.com"})

	for _, e := range events.Dispatched[UserRegistered](fake) {
		fmt.Println("dispatched", e.Email)
	}
}
Output:
dispatched ada@example.com

func NewFake

func NewFake() *Fake

NewFake returns an empty Fake.

func (*Fake) Dispatch

func (f *Fake) Dispatch(_ context.Context, event any) error

Dispatch implements Dispatcher.

type Observer added in v0.19.0

type Observer interface {
	ObserveEvent(ctx context.Context, e Event)
}

Observer is notified after every Bus.Dispatch. It runs on the caller's goroutine, so it must be fast and safe for concurrent use.

type Registration

type Registration struct {
	// contains filtered or unexported fields
}

Registration binds a listener to its event type; create it with On, OnAsync or OnQueued.

func On

func On[E any](fn func(ctx context.Context, e E) error) Registration

On registers fn for events of type E, run synchronously by Dispatch (its error is returned to the caller).

func OnAsync

func OnAsync[E any](fn func(ctx context.Context, e E) error) Registration

OnAsync registers fn for events of type E, run in the background; its error is logged.

func OnQueued added in v0.16.0

func OnQueued[E any](kind string, fn func(ctx context.Context, e E) error, opts ...queue.Option) Registration

OnQueued registers fn for events of type E as the queue job kind: Dispatch enqueues the event (encoded as JSON) and a queue worker runs fn with the queue's retries. The bus needs a queue (SetQueue; vukem.App wires App.Queue) and the job handler must be registered on it (Jobs).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL