Documentation
¶
Index ¶
- Constants
- Variables
- func IsPermanent(err error) bool
- func Meta(e Event) map[string]string
- func NewID() string
- func Permanent(err error) error
- func ResolveTopic(e Event, def string) (string, error)
- type Backoff
- type BatchPublisher
- type Cleaner
- type Event
- type Execer
- type Failure
- type Hooks
- type Option
- func WithBackoff(b Backoff) Option
- func WithBatchSize(n int) Option
- func WithCleanup(interval, retention time.Duration) Option
- func WithConcurrency(n int) Option
- func WithHooks(h Hooks) Option
- func WithLease(d time.Duration) Option
- func WithLogger(l *slog.Logger) Option
- func WithPollInterval(d time.Duration) Option
- func WithPublishTimeout(d time.Duration) Option
- func WithWorkerID(id string) Option
- type Publisher
- type PublisherFunc
- type Stats
- type Status
- type Store
- type Worker
Constants ¶
const ( HeaderID = "outbox-id" HeaderType = "outbox-type" HeaderKey = "outbox-key" )
Metadata headers attached to every message by the built-in publishers.
Variables ¶
var ErrNoTopic = Permanent(errors.New("xoutbox: event has no topic"))
ErrNoTopic is returned when neither the event nor the publisher defines a destination.
Functions ¶
func IsPermanent ¶ added in v0.1.0
IsPermanent reports whether err was wrapped with Permanent.
func NewID ¶ added in v0.1.0
func NewID() string
NewID returns a random UUIDv7 (time-ordered, index friendly).
Types ¶
type Backoff ¶ added in v0.1.0
Backoff returns the delay before the next attempt, given the attempts made so far.
func ExponentialBackoff ¶ added in v0.1.0
ExponentialBackoff doubles the delay per attempt up to max, with equal jitter.
type BatchPublisher ¶ added in v0.1.0
type BatchPublisher interface {
Publisher
PublishBatch(ctx context.Context, events []Event) []error
}
BatchPublisher is an optional fast path. The returned slice must have one entry per event (nil on success). The worker uses it automatically.
type Cleaner ¶ added in v0.1.0
type Cleaner interface {
Cleanup(ctx context.Context, retention time.Duration) (deleted int64, err error)
}
Cleaner is implemented by stores that support housekeeping. Cleanup dead-letters events whose lease expired after exhausting their attempts and, if retention > 0, deletes published events older than retention.
type Event ¶
type Event struct {
// ID uniquely identifies the event. NewEvent fills it with a UUIDv7.
// Brokers that support de-duplication (NATS JetStream) use it as the message ID.
ID string
// Topic is the destination: Kafka topic, NATS subject, RabbitMQ routing key or Redis stream.
Topic string
// Key is the partition / ordering key (e.g. an aggregate ID). Events sharing a key
// are published in insertion order. Empty means unordered.
Key string
// Type is a free-form event name such as "order.created".
Type string
Payload []byte
Headers map[string]string
// AvailableAt delays delivery until the given time. Zero means immediately.
AvailableAt time.Time
// MaxAttempts overrides the store default. Zero means the store default.
MaxAttempts int
// Set by the store when an event is claimed.
Attempts int
CreatedAt time.Time
}
Event is a message stored in the outbox and relayed to a broker.
func NewJSONEvent ¶ added in v0.1.0
NewJSONEvent marshals v as the payload and sets content-type to application/json.
func (Event) WithDelay ¶ added in v0.1.0
WithDelay returns a copy of e that will not be published before d has elapsed.
func (Event) WithHeader ¶ added in v0.1.0
WithHeader returns a copy of e with the header set.
func (Event) WithMaxAttempts ¶ added in v0.1.0
WithMaxAttempts returns a copy of e with a custom attempt limit.
type Execer ¶ added in v0.1.0
type Execer interface {
ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
}
Execer is satisfied by *sql.DB, *sql.Tx and *sql.Conn. Pass your business transaction so the event is committed atomically with your data.
type Failure ¶ added in v0.1.0
type Failure struct {
ID string
Attempts int // attempt counter to persist
Delay time.Duration // time until the event becomes claimable again
Err string
Dead bool // move to dead-letter state instead of retrying
}
Failure describes a failed delivery attempt.
type Hooks ¶ added in v0.1.0
type Hooks struct {
OnPublished func(e Event)
OnFailed func(e Event, err error, dead bool)
OnStoreError func(op string, err error)
}
Hooks are optional callbacks for metrics and tracing. They must not block.
type Option ¶ added in v0.1.0
type Option func(*options)
Option configures a Worker.
func WithBackoff ¶ added in v0.1.0
WithBackoff sets the retry delay policy (default exponential 1s..5m with jitter).
func WithBatchSize ¶ added in v0.1.0
WithBatchSize sets how many events are claimed per poll (default 100).
func WithCleanup ¶ added in v0.1.0
WithCleanup sets how often housekeeping runs (default 1m, 0 disables) and how long published events are retained (default 0 = keep forever).
func WithConcurrency ¶ added in v0.1.0
WithConcurrency sets how many events/key-groups are published in parallel (default 8).
func WithLease ¶ added in v0.1.0
WithLease sets how long claimed events stay locked to this worker (default 30s). It must comfortably exceed the time needed to publish a batch.
func WithLogger ¶ added in v0.1.0
WithLogger sets the structured logger (default slog.Default()).
func WithPollInterval ¶ added in v0.1.0
WithPollInterval sets the idle polling interval (default 1s). When a batch is full the worker polls again immediately.
func WithPublishTimeout ¶ added in v0.1.0
WithPublishTimeout bounds each Publish/PublishBatch call (default 10s).
func WithWorkerID ¶ added in v0.1.0
WithWorkerID sets the lease owner name (default host-pid-random).
type Publisher ¶
Publisher delivers a single event to a broker. Publish must return only after the broker has durably accepted the message.
type PublisherFunc ¶ added in v0.1.0
PublisherFunc adapts a function to the Publisher interface.
type Store ¶
type Store interface {
// Claim leases up to limit due events to owner for the lease duration,
// increments their attempt counter and returns them ordered by insertion.
// Events whose lease expired (crashed worker) are claimable again.
Claim(ctx context.Context, owner string, limit int, lease time.Duration) ([]Event, error)
// MarkPublished marks events as delivered.
MarkPublished(ctx context.Context, ids []string) error
// MarkFailed records a failed attempt. It must be a no-op if owner no longer holds the lease.
MarkFailed(ctx context.Context, owner string, f Failure) error
}
Store persists outbox events. Implementations must be safe for concurrent use by many workers across many processes.
type Worker ¶
type Worker struct {
// contains filtered or unexported fields
}
Worker relays events from a Store to a Publisher with at-least-once semantics. Run any number of workers across any number of processes; leases prevent double delivery under normal operation and recover events from crashed workers.
func NewWorker ¶
NewWorker creates a worker. If pub implements BatchPublisher, batches are published in one call.
func (*Worker) Notify ¶ added in v0.1.0
func (w *Worker) Notify()
Notify wakes the worker immediately, e.g. right after committing a transaction that inserted events. It never blocks.
Directories
¶
| Path | Synopsis |
|---|---|
|
internal
|
|
|
sqlstore
Package sqlstore holds the dialect-independent SQL store implementation.
|
Package sqlstore holds the dialect-independent SQL store implementation. |
|
storetest
Package storetest is a conformance suite for SQL stores.
|
Package storetest is a conformance suite for SQL stores. |
|
Package kafka publishes outbox events to Apache Kafka using IBM/sarama.
|
Package kafka publishes outbox events to Apache Kafka using IBM/sarama. |
|
Package mysql is an xoutbox.Store for MySQL 8.0+ / MariaDB 10.6+ using database/sql.
|
Package mysql is an xoutbox.Store for MySQL 8.0+ / MariaDB 10.6+ using database/sql. |
|
Package nats publishes outbox events to NATS JetStream.
|
Package nats publishes outbox events to NATS JetStream. |
|
Package postgres is an xoutbox.Store for PostgreSQL 12+ using database/sql (works with pgx/stdlib and lib/pq).
|
Package postgres is an xoutbox.Store for PostgreSQL 12+ using database/sql (works with pgx/stdlib and lib/pq). |
|
Package rabbitmq publishes outbox events to RabbitMQ with publisher confirms, persistent delivery and automatic reconnection.
|
Package rabbitmq publishes outbox events to RabbitMQ with publisher confirms, persistent delivery and automatic reconnection. |
|
Package redis publishes outbox events to Redis Streams (durable, default) or Redis Pub/Sub (fire-and-forget).
|
Package redis publishes outbox events to Redis Streams (durable, default) or Redis Pub/Sub (fire-and-forget). |