commandlog

package
v0.0.0-...-17eb08c Latest Latest
Warning

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

Go to latest
Published: Feb 28, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package commandlog provides an interface and middleware for recording every command dispatched through a CommandBus. This is a "bricks" package — bring your own backend by implementing CommandLogStore, or use a provided one.

The middleware wraps command dispatch to capture:

  • The command payload before execution (status: "pending")
  • The outcome after execution (accepted/rejected/failed, produced event IDs, duration)

Typical usage:

store := memlog.New()
bus.Use(commandlog.Middleware(store))

Index

Constants

View Source
const (
	// MaxPayloadBytes is the upper bound on Payload size (1 MB).
	MaxPayloadBytes = 1 << 20

	// MaxMetadataKeys is the upper bound on Metadata entries.
	MaxMetadataKeys = 256

	// MaxEventIDs is the upper bound on EventIDs per record.
	MaxEventIDs = 10000

	// MaxErrorLength is the upper bound on the Error string.
	MaxErrorLength = 8192

	// MaxQueryLimit caps the number of records returned by a single query.
	MaxQueryLimit = 10000

	// DefaultQueryLimit is used when QueryOpts.Limit is zero.
	DefaultQueryLimit = 100
)

Bounds — TigerStyle: every resource must be bounded.

View Source
const (
	StatusPending  = "pending"
	StatusAccepted = "accepted"
	StatusRejected = "rejected"
	StatusFailed   = "failed"
)

Status constants for CommandRecord.Status.

Variables

View Source
var (
	// ErrNotFound is returned by Get when no record matches the given ID.
	ErrNotFound = errors.New("commandlog: record not found")

	// ErrDuplicateID is returned by Record when the ID already exists.
	ErrDuplicateID = errors.New("commandlog: duplicate record ID")
)

Sentinel errors for CommandLogStore implementations.

Functions

func Middleware

func Middleware(store CommandLogStore, opts ...MiddlewareOption) command.Middleware

Middleware returns a command.Middleware that logs every command to the given store. Commands are recorded before execution (pending) and updated after (accepted/rejected/failed).

Types

type CommandLogStore

type CommandLogStore interface {
	// Record persists a command record. The record's ID must be unique.
	Record(ctx context.Context, record CommandRecord) error

	// Get retrieves a single record by ID. Returns ErrNotFound if absent.
	Get(ctx context.Context, id string) (CommandRecord, error)

	// FindByCorrelation returns all records sharing a correlation ID, ordered by Timestamp.
	FindByCorrelation(ctx context.Context, correlationID string) ([]CommandRecord, error)

	// FindByType returns records matching the command type, filtered by opts.
	FindByType(ctx context.Context, commandType string, opts QueryOpts) ([]CommandRecord, error)

	// List returns records ordered by Timestamp descending, filtered by opts.
	List(ctx context.Context, opts QueryOpts) ([]CommandRecord, error)
}

CommandLogStore persists and queries command records. Implementations must be safe for concurrent use.

type CommandRecord

type CommandRecord struct {
	// ID uniquely identifies this record.
	ID string

	// CorrelationID groups related commands (e.g. a saga).
	CorrelationID string

	// CommandType is the routed command name.
	CommandType string

	// Payload is the serialized command body. Bounded by MaxPayloadBytes.
	Payload []byte

	// Metadata holds arbitrary key-value pairs. Bounded by MaxMetadataKeys.
	Metadata map[string]string

	// Status is the execution outcome: pending, accepted, rejected, or failed.
	Status string

	// Error holds the error message if Status is rejected or failed.
	Error string

	// EventIDs lists IDs of events produced by the command. Bounded by MaxEventIDs.
	EventIDs []string

	// Duration is how long the command took to execute.
	Duration time.Duration

	// Timestamp is when the command was recorded.
	Timestamp time.Time
}

CommandRecord represents a single logged command execution.

type IDFunc

type IDFunc func() string

IDFunc generates unique IDs for command records. Default uses timestamp + random suffix via crypto/rand.

type MiddlewareOption

type MiddlewareOption func(*middlewareConfig)

MiddlewareOption configures the command log middleware.

func WithCorrelationFunc

func WithCorrelationFunc(fn func(ctx context.Context, cmd command.Command) string) MiddlewareOption

WithCorrelationFunc extracts a correlation ID from the command context. Default: empty string (no correlation).

func WithEventIDsFunc

func WithEventIDsFunc(fn func(result *command.Result) []string) MiddlewareOption

WithEventIDsFunc extracts event IDs from a command result. Default: nil (no event IDs recorded).

func WithIDFunc

func WithIDFunc(fn IDFunc) MiddlewareOption

WithIDFunc sets a custom ID generator. Default: crypto/rand hex.

func WithMetadataFunc

func WithMetadataFunc(fn func(ctx context.Context, cmd command.Command) map[string]string) MiddlewareOption

WithMetadataFunc extracts metadata from the command context. Default: nil metadata.

type QueryOpts

type QueryOpts struct {
	// Limit caps the number of results. Zero means DefaultQueryLimit; capped at MaxQueryLimit.
	Limit int

	// Offset skips this many results (for pagination).
	Offset int

	// After filters to records with Timestamp strictly after this time.
	After time.Time

	// Before filters to records with Timestamp strictly before this time.
	Before time.Time
}

QueryOpts controls filtering and pagination for list queries.

func (QueryOpts) EffectiveLimit

func (q QueryOpts) EffectiveLimit() int

EffectiveLimit returns the Limit to use, applying defaults and caps.

Jump to

Keyboard shortcuts

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