behavior

package
v0.26.0 Latest Latest
Warning

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

Go to latest
Published: May 25, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrMissingCollectorBehavior = errors.New("approval: required collector behavior missing from cqrs:behaviors group")

ErrMissingCollectorBehavior is returned by the boot-time self-check when the ActionLog or EventPublish behavior failed to register. Surfaced via fx.Invoke so misconfigured hosts cannot start a process that would silently drop audit rows / domain events.

View Source
var Module = fx.Module(
	"vef:approval:behavior",

	fx.Provide(
		fx.Annotate(
			NewTransactionBehavior,
			fx.ResultTags(`group:"vef:cqrs:behaviors"`),
		),
		fx.Annotate(
			NewActionLogBehavior,
			fx.ResultTags(`group:"vef:cqrs:behaviors"`),
		),
		fx.Annotate(
			NewEventPublishBehavior,
			fx.ResultTags(`group:"vef:cqrs:behaviors"`),
		),
	),

	fx.Invoke(
		fx.Annotate(
			assertCollectorBehaviorsRegistered,
			fx.ParamTags(`group:"vef:cqrs:behaviors"`),
		),
	),
)

Module provides all CQRS behavior middlewares for the approval module. Behaviors are aggregated via FX group `group:"vef:cqrs:behaviors"`; the CQRS bus sorts them by their Order() method so wrapping order is independent of FX's group-resolution timing.

Order assignments (see cqrs.Ordered):

  • Transaction (Order 0) wraps every inner behavior and the handler.
  • ActionLog (Order 100) persists audit rows after the handler succeeds.
  • EventPublish (Order 200) emits events last, still inside the same tx.

The fx.Invoke hook runs a boot-time self-check that fails fast if either the ActionLog or EventPublish behavior is missing — the alternative is silent audit / event loss in production, which is far worse than refusing to start.

Functions

func NewActionLogBehavior added in v0.24.0

func NewActionLogBehavior(db orm.DB) cqrs.Behavior

NewActionLogBehavior buffers ActionLog entries produced by a command handler and inserts them in a single batch after the handler succeeds. Failed handlers short-circuit so audit rows never describe a non-event.

Order positions the behavior between Transaction (outermost) and EventPublish (innermost), so logs persist inside the tx but before events emit.

func NewEventPublishBehavior added in v0.24.0

func NewEventPublishBehavior(bus event.Bus) cqrs.Behavior

NewEventPublishBehavior buffers domain events produced by a command handler and publishes them, in registration order, after the handler succeeds. Publishing runs inside the surrounding transaction so the framework's event Bus can enroll via event.WithTx(db); each event also projects its payload OccurredTime onto Envelope.OccurredAt so downstream consumers see business time rather than publish time.

Order positions the behavior as the innermost approval behavior so events only emit after the handler and ActionLog have both succeeded.

func NewTransactionBehavior

func NewTransactionBehavior(db orm.DB) cqrs.Behavior

NewTransactionBehavior creates a new TransactionBehavior.

Types

type ActionLogCollector added in v0.24.0

type ActionLogCollector = Collector[*approval.ActionLog]

ActionLogCollector is the request-scoped buffer for approval ActionLog entries. Alias of Collector[*approval.ActionLog] for call-site clarity.

func ActionLogCollectorFromContext added in v0.24.0

func ActionLogCollectorFromContext(ctx context.Context) *ActionLogCollector

ActionLogCollectorFromContext returns the request-scoped collector or a detached no-op collector (with a warning) when called outside the CQRS pipeline.

type Collector added in v0.24.0

type Collector[T any] struct {
	// contains filtered or unexported fields
}

Collector buffers items of type T produced by a command handler while it runs inside the CQRS pipeline. Handlers append items to the collector instead of touching the outside world directly; a collectorBehavior[T] flushes the buffer in one batch after the handler returns successfully.

Concrete uses live in event_publish.go (Collector[approval.DomainEvent]) and action_log.go (Collector[*approval.ActionLog]).

func TryCollectorFromContext added in v0.24.0

func TryCollectorFromContext[T any](ctx context.Context) (*Collector[T], bool)

TryCollectorFromContext returns the request-scoped Collector[T] if one is installed, else (nil, false). Use this when the absence of the collector should not produce a warning — for example, engine helpers that must fall back to direct bus.Publish when invoked from a cron or saga outside the CQRS pipeline.

func (*Collector[T]) Add added in v0.24.0

func (c *Collector[T]) Add(items ...T)

Add appends items to the collector. Nil entries — including typed-nil pointers / nil interface values — are silently dropped so call sites can pass best-effort outputs without guarding each one.

func (*Collector[T]) Items added in v0.24.0

func (c *Collector[T]) Items() []T

Items returns the buffered slice. Callers should not mutate it; the returned slice is shared with the behavior that will eventually flush it.

type EventCollector added in v0.24.0

type EventCollector = Collector[approval.DomainEvent]

EventCollector is the request-scoped buffer for approval domain events. It's just Collector[approval.DomainEvent]; the alias gives call sites a stable name even if the generic plumbing is reshaped later.

func EventCollectorFromContext added in v0.24.0

func EventCollectorFromContext(ctx context.Context) *EventCollector

EventCollectorFromContext returns the request-scoped event collector or a detached no-op collector (with a warning) when called outside the CQRS pipeline so unit tests that bypass the bus don't crash on nil receivers.

func TryEventCollectorFromContext added in v0.24.0

func TryEventCollectorFromContext(ctx context.Context) (*EventCollector, bool)

TryEventCollectorFromContext returns the collector silently when missing, for callers (engine helpers, saga drivers) that have a sensible fallback.

type TransactionBehavior

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

TransactionBehavior wraps command handlers in a database transaction. Query handlers bypass the transaction.

func (*TransactionBehavior) Handle

func (b *TransactionBehavior) Handle(ctx context.Context, action cqrs.Action, next func(context.Context) (any, error)) (any, error)

Handle wraps command actions in a database transaction. Query actions pass through unchanged. If a parent transaction is already attached to ctx (e.g. when a Saga or event subscriber re-dispatches a command from within an existing transaction), the inner pipeline reuses that transaction rather than opening a nested one — concurrent nested transactions on the same connection are driver-specific and the runtime cost of savepoints outweighs the rare benefit here.

func (*TransactionBehavior) Order added in v0.24.0

func (*TransactionBehavior) Order() int

Order places TransactionBehavior at the outermost slot so every inner behavior (ActionLog / EventPublish) sees the same tx in context.

Jump to

Keyboard shortcuts

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