gala

package
v2.3.0 Latest Latest
Warning

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

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

Documentation

Overview

Package gala provides durable, typed eventing primitives intended to replace ad-hoc in-memory dispatch patterns with a River-native foundation it's a black tie affair for your events, ensuring they arrive in style and on time

Index

Constants

View Source
const (

	// FullHighDriftThreshold is the delta above which a full-fetch schedule snaps to minimum
	FullHighDriftThreshold = 1000
	// UnlimitedErrorStreak disables error-streak exhaustion
	UnlimitedErrorStreak = -1
)
View Source
const DefaultJobTimeout = 15 * time.Minute

DefaultJobTimeout is the default maximum run time for one dispatch job

View Source
const DefaultQueueName = "events"

DefaultQueueName is the default queue used for gala durable dispatch jobs

View Source
const DefaultSoftStopTimeout = 8 * time.Second

DefaultSoftStopTimeout is the default window in-flight jobs get to finish once a stop begins

Variables

View Source
var (
	// ErrGalaRequired is returned when a nil gala runtime is used
	ErrGalaRequired = errors.New("gala: gala is required")
	// ErrRegistryRequired is returned when a nil topic registry is used
	ErrRegistryRequired = errors.New("gala: registry is required")
	// ErrTopicNameRequired is returned when a topic name is empty
	ErrTopicNameRequired = errors.New("gala: topic name is required")
	// ErrTopicAlreadyRegistered is returned when a topic is registered more than once
	ErrTopicAlreadyRegistered = errors.New("gala: topic already registered")
	// ErrTopicNotRegistered is returned when topic metadata cannot be found
	ErrTopicNotRegistered = errors.New("gala: topic not registered")
	// ErrListenerHandlerRequired is returned when a listener callback is missing
	ErrListenerHandlerRequired = errors.New("gala: listener handler is required")
	// ErrListenerHandlerConflict is returned when a listener sets both Handle and Schedule
	ErrListenerHandlerConflict = errors.New("gala: listener handle and schedule are mutually exclusive")
	// ErrListenerScheduleStateRequired is returned when a scheduled listener is missing the State extractor
	ErrListenerScheduleStateRequired = errors.New("gala: listener schedule state extractor is required")
	// ErrListenerScheduleWrapRequired is returned when a scheduled listener is missing the Wrap builder
	ErrListenerScheduleWrapRequired = errors.New("gala: listener schedule wrap builder is required")
	// ErrListenerTopicNotRegistered is returned when a listener is attached before topic registration
	ErrListenerTopicNotRegistered = errors.New("gala: listener topic not registered")
	// ErrPayloadTypeMismatch is returned when payload casting fails for a topic or listener
	ErrPayloadTypeMismatch = errors.New("gala: payload type mismatch")
	// ErrPayloadEncodeFailed is returned when payload serialization fails
	ErrPayloadEncodeFailed = errors.New("gala: payload encode failed")
	// ErrPayloadDecodeFailed is returned when payload deserialization fails
	ErrPayloadDecodeFailed = errors.New("gala: payload decode failed")
	// ErrEnvelopePayloadRequired is returned when an envelope has an empty payload
	ErrEnvelopePayloadRequired = errors.New("gala: envelope payload is required")
	// ErrJobKindRequired is returned when emit headers carry no job kind
	ErrJobKindRequired = errors.New("gala: job kind is required")
	// ErrDispatchFailed is returned when dispatch fails
	ErrDispatchFailed = errors.New("gala: dispatch failed")
	// ErrContextCodecKeyRequired is returned when a context codec key is empty
	ErrContextCodecKeyRequired = errors.New("gala: context codec key is required")
	// ErrContextCodecAlreadyRegistered is returned when a context codec key is duplicated
	ErrContextCodecAlreadyRegistered = errors.New("gala: context codec already registered")
	// ErrContextSnapshotCaptureFailed is returned when snapshot capture fails
	ErrContextSnapshotCaptureFailed = errors.New("gala: context snapshot capture failed")
	// ErrContextSnapshotRestoreFailed is returned when snapshot restore fails
	ErrContextSnapshotRestoreFailed = errors.New("gala: context snapshot restore failed")
	// ErrRiverDispatchJobEnvelopeRequired is returned when a river dispatch job has no envelope payload
	ErrRiverDispatchJobEnvelopeRequired = errors.New("gala: river dispatch job envelope is required")
	// ErrRiverEnvelopeEncodeFailed is returned when encoding a river envelope payload fails
	ErrRiverEnvelopeEncodeFailed = errors.New("gala: river envelope encode failed")
	// ErrRiverEnvelopeDecodeFailed is returned when decoding a river envelope payload fails
	ErrRiverEnvelopeDecodeFailed = errors.New("gala: river envelope decode failed")
	// ErrRiverDispatchInsertFailed is returned when inserting a durable river dispatch job fails
	ErrRiverDispatchInsertFailed = errors.New("gala: river dispatch insert failed")
	// ErrRiverListenerCleanupFailed is returned when detached-listener jobs cannot be purged
	ErrRiverListenerCleanupFailed = errors.New("gala: river listener cleanup failed")
	// ErrRiverConnectionURIRequired is returned when river runtime setup is missing a connection URI
	ErrRiverConnectionURIRequired = errors.New("gala: river connection URI is required")
	// ErrRiverClientInitializationFailed is returned when building the river queue client fails
	ErrRiverClientInitializationFailed = errors.New("gala: river client initialization failed")
	// ErrRiverWorkerStartFailed is returned when starting gala river workers fails
	ErrRiverWorkerStartFailed = errors.New("gala: river worker start failed")
	// ErrRiverWorkerStopFailed is returned when stopping gala river workers fails
	ErrRiverWorkerStopFailed = errors.New("gala: river worker stop failed")
	// ErrRiverClientCloseFailed is returned when closing the gala river queue client fails
	ErrRiverClientCloseFailed = errors.New("gala: river client close failed")
	// ErrDispatchModeInvalid is returned when an unknown gala dispatch mode is configured.
	ErrDispatchModeInvalid = errors.New("gala: dispatch mode is invalid")
	// ErrListenerPanicked is returned when a listener panics during execution
	ErrListenerPanicked = errors.New("gala: listener panicked")
)
View Source
var (
	// Mutation carries mutation event envelopes
	Mutation = NewKind("mutation")
	// Workflow carries workflow command envelopes
	Workflow = NewKind("workflow")
	// IntegrationRun carries one-shot integration operation envelopes
	IntegrationRun = NewKind("integration.run")
	// IntegrationReconcile carries recurring reconcile and scheduled cycle envelopes
	IntegrationReconcile = NewKind("integration.reconcile")
	// IntegrationIngest carries ingest persistence envelopes
	IntegrationIngest = NewKind("integration.ingest")
	// IntegrationWebhook carries inbound webhook envelopes
	IntegrationWebhook = NewKind("integration.webhook")
	// System carries startup and maintenance envelopes
	System = NewKind("system")
)

root namespaces for every durable envelope family; each one is a river job kind and the canonical topic prefix its families derive from

View Source
var DirectorySyncRunIDKey = contextx.NewKey[string]()

DirectorySyncRunIDKey carries the directory sync run id to downstream ingest handlers

View Source
var ErrListenerGated = errors.New("gala: listener gated")

ErrListenerGated signals a gated skip so executeListener suppresses delivery metrics

View Source
var OperationContextKey = contextx.NewKey[OperationContext]()

OperationContextKey stores durable entity-object operation metadata on a context

View Source
var WorkflowFlagsKey = contextx.NewKey[WorkflowFlags]()

WorkflowFlagsKey stores the workflow bypass controls in context

Functions

func DecodeAttributes

func DecodeAttributes[T any](c OperationContext) (T, error)

DecodeAttributes decodes the source-specific provenance payload into T

func ReplaceValue

func ReplaceValue[T any](g *Gala, value T) (func(), error)

ReplaceValue swaps a typed runtime dependency and returns an idempotent restore function

func Resolve

func Resolve[T any](ctx context.Context, injector do.Injector, listener string) (T, bool)

Resolve resolves a listener dependency from the injector, reporting false when the dependency is not wired so the listener can skip the event

func SanitizeTag

func SanitizeTag(s string) string

SanitizeTag returns a River-compatible tag: non-word/hyphen chars replaced with `_`, leading and trailing hyphens replaced with `_`, truncated to 255 characters

func SetAttributes

func SetAttributes[T any](c *OperationContext, attributes T) error

SetAttributes marshals a source-specific provenance payload onto the context

func WithOperationContext

func WithOperationContext(ctx context.Context, oc OperationContext) context.Context

WithOperationContext stores operation metadata on the supplied context

Types

type AttachOption

type AttachOption func(*Gala) error

AttachOption provisions one dependency or durable context codec onto a gala runtime

func WithRestoredValue

func WithRestoredValue[T any](id ContextKey, setter func(context.Context, T) context.Context) AttachOption

WithRestoredValue registers a durable context codec that re-resolves a live dependency from the runtime's injector on the handler side and attaches it to the restored context

func WithValue

func WithValue[T any](value T) AttachOption

WithValue provides a typed dependency that listeners resolve via HandlerContext.Injector

type Config

type Config struct {
	// DispatchMode controls whether events are dispatched durably (River) or in-memory.
	DispatchMode DispatchMode
	// ConnectionURI is the database connection URI used for the dedicated gala river client
	ConnectionURI string
	// QueueName is the gala queue used for durable dispatch jobs
	QueueName string
	// WorkerCount is the max worker concurrency for the gala queue
	WorkerCount int
	// MaxRetries sets max attempts for gala dispatch jobs when greater than zero
	MaxRetries int
	// RunMigrations enables River schema migrations on startup (use for tests only)
	RunMigrations bool
	// FetchCooldown is the minimum time between job fetches per worker (default 100ms, min 1ms)
	// Lower values increase throughput but also database load. River enforces 1ms minimum.
	FetchCooldown time.Duration
	// FetchPollInterval is the fallback polling interval when LISTEN/NOTIFY misses events (default 1s)
	// This is only used when LISTEN/NOTIFY fails to deliver notifications.
	FetchPollInterval time.Duration
	// Kinds are the envelope kind namespaces this runtime registers alongside the default
	// dispatch kind; each kind gets a dedicated queue and shares the envelope worker
	Kinds []Namespace
	// TopicRenames maps retired topic names to their designated replacements, applied to
	// queued envelopes at dispatch and during job migration
	TopicRenames map[TopicName]TopicName
	// OperationRenames maps retired payload operation strings to their designated replacements
	OperationRenames map[string]string
	// JobTimeout is the maximum run time for one dispatch job; long-running batch
	// operations need far more than River's one-minute default
	JobTimeout time.Duration
	// SoftStopTimeout is how long in-flight jobs may keep running after a stop begins
	// before their contexts are cancelled
	SoftStopTimeout time.Duration
}

Config configures cohesive Gala startup

type ContextCodec

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

ContextCodec captures and restores one durable context value; construct via NewKeyCodec or a codec builder, never as a bare literal

func NewKeyCodec

func NewKeyCodec[T any](id ContextKey, key contextx.Key[T]) ContextCodec

NewKeyCodec creates a codec that captures and restores values from key using id as the stable JSON snapshot identifier

func OperationContextCodec

func OperationContextCodec() ContextCodec

OperationContextCodec returns the durable context codec for OperationContext propagation

type ContextKey

type ContextKey = string

ContextKey identifies a restorable context value key using string alias for better readability and to avoid collisions with other context keys this has to be a string to be used as a JSON key for durability rather than a strict type + contextx

type ContextManager

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

ContextManager manages context codecs and snapshot round-trips; codecs are registered during wiring only, so snapshot round-trips read the codec map without locking

func (*ContextManager) Capture

func (m *ContextManager) Capture(ctx context.Context) (ContextSnapshot, error)

Capture captures all registered context codec values

func (*ContextManager) Register

func (m *ContextManager) Register(codec ContextCodec) error

Register registers a context codec by key

func (*ContextManager) Restore

func (m *ContextManager) Restore(ctx context.Context, snapshot ContextSnapshot) (context.Context, error)

Restore restores snapshot values into a new context

type ContextSnapshot

type ContextSnapshot struct {
	// Values contains codec-managed context values
	Values map[ContextKey]json.RawMessage `json:"values,omitempty"`
}

ContextSnapshot captures context data that can be restored after durable hops

type Definition

type Definition[T any] struct {
	// Topic is the topic handled by this listener
	Topic Topic[T]
	// Name is the stable listener name; empty defaults to the topic name
	Name string
	// Operations optionally scopes listener interest to specific mutation operations
	// Empty means the listener accepts all operations for the topic
	Operations []string
	// Gate optionally drops the event silently when it returns false; it receives the
	// restored context before any caller or context-key mutation
	Gate func(context.Context, T) bool
	// Caller optionally replaces or augments the restored caller (never nil)
	Caller func(restored *auth.Caller, payload T) *auth.Caller
	// ContextKeys are applied to the context in order before the handler runs
	ContextKeys []func(context.Context) context.Context
	// LogFields is merged over the automatic dispatch log fields
	LogFields func(T) map[string]any
	// Cancel optionally classifies a handler error as terminal, converting it to river.JobCancel
	Cancel func(context.Context, T, error) bool
	// OnExhausted runs when a scheduled loop stops on its error-streak budget
	OnExhausted func(context.Context, T, error)
	// Schedule makes this listener a self-sustaining adaptive re-emit loop when non-nil;
	// exactly one of Handle and Schedule.Handle must be set
	Schedule *ScheduleSpec[T]
	// Handle is the callback invoked for this listener
	Handle Handler[T]
}

Definition defines one listener binding

func (Definition[T]) Attach

func (d Definition[T]) Attach(g *Gala) (ListenerID, error)

Attach registers the definition's topic contract and listener on the runtime

type DispatchMode

type DispatchMode string

DispatchMode controls whether envelopes are dispatched durably or in-memory.

const (
	// DispatchModeDurable persists envelopes in River before worker execution.
	DispatchModeDurable DispatchMode = "durable"
	// DispatchModeInMemory dispatches envelopes immediately in-process.
	DispatchModeInMemory DispatchMode = "in_memory"
)

type EmitOption

type EmitOption func(*Envelope)

EmitOption customizes one emitted envelope before dispatch

func WithEventID

func WithEventID(id EventID) EmitOption

WithEventID sets an explicit event identifier on the emitted envelope, making the caller's identity (e.g. a mutation event id or run id) the durable dedup and traceability key instead of a freshly minted ULID

func WithRawPayload

func WithRawPayload(raw json.RawMessage) EmitOption

WithRawPayload emits pre-encoded payload bytes, bypassing the topic codec. The payload argument passed to Emit is ignored when set; the topic must still be registered so listeners can decode at dispatch time

type Envelope

type Envelope struct {
	// ID is the unique event identifier
	ID EventID `json:"id"`
	// Topic is the destination topic
	Topic TopicName `json:"topic"`
	// OccurredAt is the emit timestamp in UTC
	OccurredAt time.Time `json:"occurred_at"`
	// Headers holds operational metadata
	Headers Headers `json:"headers"`
	// Payload is encoded topic payload data
	Payload json.RawMessage `json:"payload"`
	// ContextSnapshot holds restorable context metadata
	ContextSnapshot ContextSnapshot `json:"context_snapshot"`
}

Envelope is the durable event envelope

type EnvelopeArgs

type EnvelopeArgs struct {
	// Envelope is the encoded gala envelope payload
	Envelope []byte `json:"envelope"`
	// UniqueKey scopes the ByArgs uniqueness hash to this field alone via the river tag
	UniqueKey string `json:"unique_key,omitempty" river:"unique"`
}

EnvelopeArgs is the durable dispatch payload

func (EnvelopeArgs) EnvelopePayload

func (a EnvelopeArgs) EnvelopePayload() []byte

EnvelopePayload returns the encoded envelope bytes

func (EnvelopeArgs) Kind

func (EnvelopeArgs) Kind() string

Kind satisfies river.JobArgs with the legacy dispatch kind

func (EnvelopeArgs) KindAliases

func (EnvelopeArgs) KindAliases() []string

KindAliases registers the shared envelope worker for every configured job kind

type EventID

type EventID string

EventID is a stable identifier for traceability; callers may override the generated value via WithEventID

func NewEventID

func NewEventID() EventID

NewEventID creates a new event identifier

type Gala

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

Gala provides cohesive event dispatch + worker lifecycle management no black tie required, but a riverboat and some confetti wouldn't hurt

func NewGala

func NewGala(ctx context.Context, config Config) (app *Gala, err error)

NewGala initializes your gala, initializes dependencies, and starts workers

func (*Gala) Attach

func (g *Gala) Attach(opts ...AttachOption) error

Attach provisions dependencies and durable context codecs onto the runtime. It is called during wiring, after construction and before the first emit that relies on the provisioned values; registration failures are wiring errors

func (*Gala) Close

func (g *Gala) Close() error

Close closes the dedicated Gala queue client

func (*Gala) CountActiveJobsWithMetadata

func (g *Gala) CountActiveJobsWithMetadata(ctx context.Context, metadataFragment string) (int, error)

CountActiveJobsWithMetadata returns how many River jobs whose metadata JSONB contains the given fragment are in an active state. Returns zero without error when Gala is not in durable mode

func (*Gala) EmitWithHeaders

func (g *Gala) EmitWithHeaders(ctx context.Context, topic TopicName, payload any, headers Headers, opts ...EmitOption) (EventID, error)

EmitWithHeaders emits a payload to the topic under the given headers, applying any options to the envelope before dispatch, and returns the emitted event identifier; headers must carry a job kind

func (*Gala) HasActiveJobWithMetadata

func (g *Gala) HasActiveJobWithMetadata(ctx context.Context, metadataFragment string) (bool, error)

HasActiveJobWithMetadata reports whether at least one active-state River job matches the metadata fragment; false without error when Gala is not durable

func (*Gala) InterestedIn

func (g *Gala) InterestedIn(topic TopicName, operation string) bool

InterestedIn reports whether any registered listener matches the topic, operation, and soft-delete disposition

func (*Gala) PurgeActiveJobsWithMetadata

func (g *Gala) PurgeActiveJobsWithMetadata(ctx context.Context, metadataFragment string) (int, error)

PurgeActiveJobsWithMetadata deletes live River jobs matching a JSONB metadata fragment Running jobs are cancelled before deletion and rescanned for recurring successors

func (*Gala) RemoveListeners

func (g *Gala) RemoveListeners(ctx context.Context, ids ...ListenerID) error

RemoveListeners detaches listeners and purges jobs no remaining listener can handle Failed cleanup remains retryable with the same IDs

func (*Gala) StartWorkers

func (g *Gala) StartWorkers(ctx context.Context) error

StartWorkers starts Gala workers

func (*Gala) StopWorkers

func (g *Gala) StopWorkers(ctx context.Context) error

StopWorkers stops Gala workers

func (*Gala) WaitIdle

func (g *Gala) WaitIdle(ctx context.Context) error

WaitIdle blocks until runnable work drains or the context ends Future scheduled and retry work does not count as busy in durable mode

type Handler

type Handler[T any] func(HandlerContext, T) error

Handler processes a typed event payload

type HandlerContext

type HandlerContext struct {
	// Context is the restored event context used for listener execution
	Context context.Context
	// Envelope is the envelope being processed
	Envelope Envelope
	// Injector provides typed dependency lookup via samber/do
	Injector do.Injector
	// Caller is the pre-resolved caller for this dispatch
	Caller *auth.Caller
}

HandlerContext provides event context and dependency resolution scope for listeners

type Headers

type Headers struct {
	// Properties stores additional metadata for UI visibility
	Properties map[string]string `json:"properties,omitempty"`
	// Tags are low-cardinality labels forwarded to the transport layer (e.g. River job tags)
	Tags []string `json:"tags,omitempty"`
	// Listeners are the registered listener names for the topic, populated at dispatch time
	Listeners []string `json:"listeners,omitempty"`
	// Kind optionally routes dispatch to a registered job kind
	Kind string `json:"kind,omitempty"`
	// ScheduledAt defers execution until the specified time; nil means immediate
	ScheduledAt *time.Time `json:"scheduled_at,omitempty"`
	// UniqueKey enforces at most one live job per key at insert time
	UniqueKey string `json:"unique_key,omitempty"`
	// SkipUniqueKey suppresses the topic's UniqueKey derivation
	SkipUniqueKey bool `json:"skip_unique_key,omitempty"`
	// UniqueOnce extends UniqueKey matching to terminal job states
	UniqueOnce bool `json:"unique_once,omitempty"`
	// Metadata carries structured operation context as opaque JSON
	Metadata json.RawMessage `json:"metadata,omitempty"`
}

Headers defines operational metadata for an envelope

type ListenerError

type ListenerError struct {
	// ListenerName is the name of the listener that failed
	ListenerName string
	// Cause is the underlying error from the listener
	Cause error
	// Panicked indicates whether the listener panicked
	Panicked bool
}

ListenerError captures a listener execution failure with context

func (ListenerError) Error

func (e ListenerError) Error() string

Error returns an error message for listener execution failures

func (ListenerError) Unwrap

func (e ListenerError) Unwrap() error

Unwrap returns the underlying cause for use with errors.Is and errors.As

type ListenerID

type ListenerID string

ListenerID identifies a registered listener

func Register

func Register(g *Gala, registrations ...Registration) ([]ListenerID, error)

Register registers listener values of any payload type through the single registration path

type Namespace

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

Namespace is one node in the durable naming tree: a job kind at the root, topic families below

func JobKinds

func JobKinds() []Namespace

JobKinds returns every root namespace a durable runtime registers by default

func NewKind

func NewKind(name string) Namespace

NewKind declares the job kind gala.<name> whose canonical topic prefix is <name>.

func (Namespace) At

func (n Namespace) At(prefix string) Namespace

At returns the namespace rehomed at the given prefix, keeping the job kind

func (Namespace) Child

func (n Namespace) Child(segment string) Namespace

Child returns the namespace one segment deeper, keeping the parent's job kind

func (Namespace) Key

func (n Namespace) Key(segments ...string) string

Key mints a colon-delimited insert-time dedup key under the namespace's prefix

func (Namespace) Kind

func (n Namespace) Kind() string

Kind returns the job kind this namespace's topics dispatch under

func (Namespace) Name

func (n Namespace) Name(suffix string) TopicName

Name mints a topic name in this namespace

func (Namespace) Prefixed

func (n Namespace) Prefixed(segment string) Namespace

Prefixed returns the namespace with a segment prepended to its prefix, keeping the job kind

func (Namespace) Queue

func (n Namespace) Queue() string

Queue returns the river queue name for the namespace's job kind

type OperationContext

type OperationContext struct {
	// OwnerID is the owning organization for the operation
	OwnerID string `json:"ownerId,omitempty" jsonschema:"description=Owning organization identifier"`
	// Operation is the mutation type when applicable: CREATE, UPDATE, DELETE
	Operation string `json:"operation,omitempty" jsonschema:"description=Mutation type when applicable: CREATE, UPDATE, DELETE"`
	// EntityID is the identifier of the entity the operation targets
	EntityID string `json:"entityId,omitempty" jsonschema:"description=Identifier of the target entity"`
	// EntityType is the schema type of the target entity
	EntityType string `json:"entityType,omitempty" jsonschema:"description=Schema type of the target entity"`
	// Attributes is the source-specific provenance payload, decoded on demand
	Attributes json.RawMessage `json:"attributes,omitempty" jsonschema:"description=Source-specific provenance payload"`
}

OperationContext is the durable entity-object metadata attached to event dispatch and restored on the handling side; authentication context (organization, user) travels with auth.Caller and is intentionally not duplicated here

func OperationContextFromContext

func OperationContextFromContext(ctx context.Context) (OperationContext, bool)

OperationContextFromContext returns operation metadata from context when present

func (OperationContext) PayloadOperation

func (c OperationContext) PayloadOperation() string

PayloadOperation returns the operation for gala listener routing; payloads embedding OperationContext satisfy the PayloadOperation contract through promotion

func (OperationContext) Properties

func (c OperationContext) Properties() map[string]string

Properties returns the context as a flat string map for gala header visibility

type PayloadOperation

type PayloadOperation interface {
	PayloadOperation() string
}

PayloadOperation is the payload contract for listener operation routing; payloads without it dispatch with an empty operation

type PayloadOperationRenamer

type PayloadOperationRenamer interface {
	WithPayloadOperation(operation string) any
}

PayloadOperationRenamer is an optional payload contract for operation renames, returning a copy of the payload carrying the renamed operation

type Pool

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

Pool is a lightweight in-memory task pool exposed from gala

func NewPool

func NewPool(opts ...PoolOption) *Pool

NewPool creates an in-memory task pool

func (*Pool) Release

func (p *Pool) Release()

Release stops workers and waits for completion

func (*Pool) Submit

func (p *Pool) Submit(task func())

Submit schedules one task

func (*Pool) SubmitMultipleAndWait

func (p *Pool) SubmitMultipleAndWait(tasks []func()) error

SubmitMultipleAndWait schedules all tasks and waits for completion

func (*Pool) WaitIdle

func (p *Pool) WaitIdle(ctx context.Context) error

WaitIdle blocks until stable idleness or context cancellation

type PoolOption

type PoolOption func(*Pool)

PoolOption configures a pool instance

func WithPoolName

func WithPoolName(name string) PoolOption

WithPoolName sets the pool name (reserved for metrics labeling)

func WithWorkers

func WithWorkers(n int) PoolOption

WithWorkers sets maximum worker concurrency

type Registration

type Registration interface {
	// Attach registers the listener and its topic contract on the runtime
	Attach(g *Gala) (ListenerID, error)
}

Registration is one listener registration value: Definition implements it directly and declarative config structs implement it by compiling to a Definition

type Schedule

type Schedule struct {
	// MinInterval is the shortest allowed interval between runs
	MinInterval time.Duration `json:"min_interval"`
	// MaxInterval is the longest allowed interval between runs
	MaxInterval time.Duration `json:"max_interval"`
	// BackoffFactor is the multiplier applied when backing off (idle or error)
	BackoffFactor float64 `json:"backoff_factor"`
	// HighDriftThreshold is the delta count above which the interval resets to MinInterval
	HighDriftThreshold int `json:"high_drift_threshold"`
	// MaxErrorStreak stops the loop after this many consecutive failed cycles; UnlimitedErrorStreak disables exhaustion
	MaxErrorStreak int `json:"max_error_streak"`
}

Schedule defines the adaptive scheduling policy for recurring work

func NewFullFetchSchedule

func NewFullFetchSchedule() *Schedule

NewFullFetchSchedule creates a Schedule suited for operations that always fetch all records and cannot do incremental syncs, using an hour as the minimum interval

func (Schedule) Next

func (s Schedule) Next(state ScheduleState, delta int, err error) ScheduleState

Next computes the next scheduling state from the current state and run outcome. A non-nil error signals a failed run; delta is the number of records that changed

type ScheduleSpec

type ScheduleSpec[T any] struct {
	// Schedule controls adaptive interval computation
	Schedule Schedule
	// Handle is the handler invoked each cycle
	Handle func(context.Context, T) (int, error)
	// State extracts the ScheduleState from the envelope
	State func(T) ScheduleState
	// Wrap builds a new envelope carrying the updated ScheduleState
	Wrap func(T, ScheduleState) T
	// PrepareEmit optionally enriches the context and headers before re-emitting
	PrepareEmit func(context.Context, T) (context.Context, Headers)
	// Override optionally returns a per-envelope schedule that overrides Schedule
	Override func(T) *Schedule
}

ScheduleSpec declares the adaptive re-emit loop for a scheduled listener definition

type ScheduleState

type ScheduleState struct {
	// Incarnation identifies one logical schedule chain across every cycle
	Incarnation string `json:"incarnation,omitempty"`
	// Interval is the current scheduling interval
	Interval time.Duration `json:"interval"`
	// IdleStreak is the number of consecutive runs with zero delta
	IdleStreak int `json:"idle_streak"`
	// ErrorStreak is the number of consecutive runs that returned an error
	ErrorStreak int `json:"error_streak"`
	// Cycle is the monotonic cycle counter
	Cycle int `json:"cycle"`
}

ScheduleState carries adaptive scheduling state across dispatch cycles

func (ScheduleState) NextScheduledAt

func (s ScheduleState) NextScheduledAt() time.Time

NextScheduledAt returns the wall-clock time for the next run based on the computed state

type Topic

type Topic[T any] struct {
	// Name is the stable topic identifier
	Name TopicName
	// Kind is the job kind emissions on this topic dispatch under
	Kind string
	// UniqueKey optionally derives Headers.UniqueKey from the payload for every emission on the topic
	UniqueKey func(T) string
}

Topic defines a strongly typed topic contract

func NamespacedTopic

func NamespacedTopic[T any](n Namespace, suffix string, opts ...TopicOption[T]) Topic[T]

NamespacedTopic constructs a typed topic in the namespace, carrying its kind

func NamespacedTopicFor

func NamespacedTopicFor[T any](n Namespace, opts ...TopicOption[T]) Topic[T]

NamespacedTopicFor constructs a typed topic named by the payload's JSON schema identifier

type TopicName

type TopicName string

TopicName is the stable string identifier for a topic

type TopicOption

type TopicOption[T any] func(*Topic[T])

TopicOption configures a constructed topic

func WithUniqueKey

func WithUniqueKey[T any](derive func(T) string) TopicOption[T]

WithUniqueKey sets the topic's insert-time uniqueness derivation

type WorkflowFlags

type WorkflowFlags struct {
	// Bypass skips workflow approval interceptors for system operations
	Bypass bool `json:"bypass,omitempty"`
	// AllowEventEmission keeps workflow listener execution enabled while Bypass is set
	AllowEventEmission bool `json:"allow_event_emission,omitempty"`
}

WorkflowFlags carries the workflow bypass controls across durable dispatch hops

Jump to

Keyboard shortcuts

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