deadletter

package
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Oct 3, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package deadletter is the eventing dead-letter queue PORT (ADR-0118, F85): the durable park for a Sensor action-delivery that failed past the bounded retry cap. It is deliberately BUS-DRIVER-INDEPENDENT — the same store serves the in-memory and NATS buses, so the reliability guarantee never hinges on a JetStream feature (this package imports NO bus). Records are engine-minted, high-volume operational data (like the ADR-0094 run store), NOT a CRD: they live in a dedicated Badger instance surfaced by a read + replay/discard control-plane surface, never the metastore.

The port has two V1 drivers, each in its own subpackage, both held to the shared Contract: badger (in-memory mode for tests/dev, on-disk for production) and memory (a small pure-map driver for cross-platform tests). See deadletter/badger and deadletter/memory.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Contract

func Contract(t *testing.T, newStore func(t *testing.T) Store)

Contract exercises the deadletter.Store port against a driver. Every driver's test runs it (ADR-0002 shared contract suite), so badger and memory are held to one behavior: roundtrip, not-found, list newest-first + namespace scope, delete (idempotent), no-aliasing, and the retention sweep (TTL + per-ns cap). It is the `retention-evicts`, `discard-removes` and `driver-independent` store-level evidence.

Types

type DeadLetter

type DeadLetter struct {
	ID        string           `json:"id"`        // ULID — time-sortable within a namespace (cheap cap eviction)
	Namespace v1.NamespaceName `json:"namespace"` //
	Sensor    v1.ObjectName    `json:"sensor"`    // the Sensor whose action failed
	Source    v1.ObjectName    `json:"source"`    // the EventSource — from the delivery unit's dependency tuple
	Event     v1.ObjectName    `json:"event"`     // the event name — from the delivery unit's dependency tuple
	Action    string           `json:"action"`    // the Sensor action name (do[].name)
	Payload   json.RawMessage  `json:"payload"`   // the full CloudEvent JSON (re-injected verbatim on replay)
	Attempts  int              `json:"attempts"`  // delivery attempts made before dead-lettering
	Reason    string           `json:"reason"`    // the terminal delivery error
	FailedAt  time.Time        `json:"failedAt"`  //
}

DeadLetter is a terminally-undeliverable Sensor action, parked for inspection/replay. It carries the full firing CloudEvent (Payload) so replay can re-inject it verbatim, plus the provenance to re-find the action on the LIVE Sensor spec. It is built from the Sensor's in-memory delivery unit (the dependency's source/event tuple), never by re-parsing the CloudEvent.

func Clone

func Clone(dl DeadLetter) (DeadLetter, error)

Clone deep-copies a record so drivers never alias caller-owned memory.

type Store

type Store interface {
	// Put creates or replaces a dead-letter record (replace is how replay re-parks on repeat failure).
	Put(ctx context.Context, dl DeadLetter) error
	// List returns a namespace's dead letters, newest first (ID descending).
	List(ctx context.Context, ns v1.NamespaceName) ([]DeadLetter, error)
	// Get returns one record, or fault.NotFound if absent.
	Get(ctx context.Context, ns v1.NamespaceName, id string) (DeadLetter, error)
	// Delete removes a record (discard / replay-success); absent is not an error.
	Delete(ctx context.Context, ns v1.NamespaceName, id string) error
	// SweepExpired is store-global (no ns) and iterates ALL namespaces: the TTL is global — it evicts
	// entries older than retention across every namespace — while the count cap is enforced per-namespace,
	// by grouping keys under each dl/<ns>/ prefix and evicting the oldest over-cap in each. retention<=0
	// disables the TTL; maxPerNS<=0 disables the cap. Returns the number of records evicted.
	SweepExpired(ctx context.Context, retention time.Duration, maxPerNS int) (int, error)
	// Close releases the driver's resources.
	Close() error
}

Store is the dead-letter queue port (ADR-0002 §1) — bus-driver-independent. Records are engine-owned operational data, not a CRD. Implementations are the single source of truth for parked failures.

Directories

Path Synopsis
Package badger is the dead-letter-queue deadletter driver (ADR-0118), backed by Badger v4 in a DEDICATED instance (never the metastore).
Package badger is the dead-letter-queue deadletter driver (ADR-0118), backed by Badger v4 in a DEDICATED instance (never the metastore).
Package memory is the in-memory deadletter.Store driver (ADR-0118): a small pure-Go map with no files, for cross-platform tests and the InMemory preset.
Package memory is the in-memory deadletter.Store driver (ADR-0118): a small pure-Go map with no files, for cross-platform tests and the InMemory preset.

Jump to

Keyboard shortcuts

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