Documentation
¶
Overview ¶
Package postgres provides pgx-backed transactional persistence for outbox envelopes. Writer methods only accept pgx.Tx so callers cannot accidentally use a pool or connection and lose application-write atomicity.
Index ¶
- Variables
- func Migrations() fs.FS
- type ArchiveFunc
- type Archiver
- type BacklogStats
- type Claim
- type ClaimRequest
- type DeadArchiveFunc
- type DeadArchiver
- type DeadMessage
- type DeliveredMessage
- type InspectRequest
- type LeaseRef
- type MessageState
- type MessageSummary
- type ReplayRequest
- type SerializationMode
- type Store
- func (s *Store) ArchiveAndPruneDead(ctx context.Context, cutoff time.Time, limit int, archiver DeadArchiver) (ids []string, err error)
- func (s *Store) ArchiveAndPruneDelivered(ctx context.Context, cutoff time.Time, limit int, archiver Archiver) (ids []string, err error)
- func (s *Store) Backlog(ctx context.Context) (BacklogStats, error)
- func (s *Store) Claim(ctx context.Context, request ClaimRequest) ([]Claim, error)
- func (s *Store) DeadLetter(ctx context.Context, lease LeaseRef, cause error) error
- func (s *Store) ExtendLease(ctx context.Context, lease LeaseRef, duration time.Duration) (time.Time, error)
- func (s *Store) Inspect(ctx context.Context, request InspectRequest) ([]MessageSummary, error)
- func (s *Store) MarkDelivered(ctx context.Context, lease LeaseRef) error
- func (s *Store) Ping(ctx context.Context) error
- func (s *Store) PruneDead(ctx context.Context, cutoff time.Time, limit int) (ids []string, err error)
- func (s *Store) PruneDelivered(ctx context.Context, cutoff time.Time, limit int) (ids []string, err error)
- func (s *Store) ReleaseLease(ctx context.Context, lease LeaseRef) error
- func (s *Store) Replay(ctx context.Context, request ReplayRequest) (ids []string, err error)
- func (s *Store) Retry(ctx context.Context, lease LeaseRef, availableAt time.Time, cause error) error
- type StoreConfig
- type Writer
- type WriterConfig
Constants ¶
This section is empty.
Variables ¶
var ( ErrPoolRequired = errors.New("outbox/postgres: pool is required") ErrClaimOwnerRequired = errors.New("outbox/postgres: claim owner is required") ErrInvalidClaimLimit = errors.New("outbox/postgres: claim limit is outside configured bounds") ErrInvalidLeaseDuration = errors.New("outbox/postgres: lease duration is outside configured bounds") ErrLeaseLost = errors.New("outbox/postgres: lease is no longer owned") ErrInvalidAdminLimit = errors.New("outbox/postgres: administrative batch is outside configured bounds") ErrReplayIDsRequired = errors.New("outbox/postgres: replay IDs are required") ErrReplayRequestedBy = errors.New("outbox/postgres: replay requester is required") ErrReplayReasonRequired = errors.New("outbox/postgres: replay reason is required") ErrReplayDuplicateID = errors.New("outbox/postgres: replay IDs must be unique") ErrReplayConflict = errors.New("outbox/postgres: replay selection contains missing or non-terminal records") ErrPruneCutoffRequired = errors.New("outbox/postgres: prune cutoff is required") ErrArchiverRequired = errors.New("outbox/postgres: archiver is required") ErrInvalidMessageState = errors.New("outbox/postgres: message state is invalid") ErrInvalidSerialization = errors.New("outbox/postgres: serialization mode is invalid") )
var ( ErrEmptyBatch = errors.New("outbox/postgres: batch is empty") ErrBatchTooLarge = errors.New("outbox/postgres: batch exceeds configured limit") ErrInvalidBatchLimit = errors.New("outbox/postgres: batch limit is invalid") ErrTransactionRequired = errors.New("outbox/postgres: caller transaction is required") )
Functions ¶
func Migrations ¶
Migrations returns the versioned migration files rooted at their filenames. The returned fs.FS can be consumed by go-migrations or another migration runner without exposing a Goose dependency to applications.
Types ¶
type ArchiveFunc ¶
type ArchiveFunc func(context.Context, []DeliveredMessage) error
ArchiveFunc adapts a function to Archiver.
func (ArchiveFunc) Archive ¶
func (archive ArchiveFunc) Archive(ctx context.Context, messages []DeliveredMessage) error
Archive forwards delivered messages to the wrapped function.
type Archiver ¶
type Archiver interface {
Archive(context.Context, []DeliveredMessage) error
}
Archiver persists delivered messages before the store deletes them. Implementations must tolerate duplicates because a successful archive can be followed by an ambiguous PostgreSQL commit.
type BacklogStats ¶
type BacklogStats = outbox.BacklogStats
BacklogStats is the root payload-free backlog summary type.
type Claim ¶
Claim is an envelope together with the ownership proof required for every subsequent state transition.
type ClaimRequest ¶
type ClaimRequest struct {
Owner string
Limit int
LeaseDuration time.Duration
Serialization SerializationMode
}
ClaimRequest describes one bounded lease acquisition.
type DeadArchiveFunc ¶
type DeadArchiveFunc func(context.Context, []DeadMessage) error
DeadArchiveFunc adapts a function to DeadArchiver.
func (DeadArchiveFunc) ArchiveDead ¶
func (archive DeadArchiveFunc) ArchiveDead(ctx context.Context, messages []DeadMessage) error
ArchiveDead forwards dead letters to the wrapped function.
type DeadArchiver ¶
type DeadArchiver interface {
ArchiveDead(context.Context, []DeadMessage) error
}
DeadArchiver persists dead letters before the store deletes them.
type DeadMessage ¶
DeadMessage contains immutable message data and terminal failure context for a dead-letter archive.
type DeliveredMessage ¶
DeliveredMessage contains the immutable message data supplied to an archive-before-delete hook.
type InspectRequest ¶
type InspectRequest struct {
State MessageState
Topic string
Before time.Time
Limit int
}
InspectRequest selects a bounded administrative summary batch.
type LeaseRef ¶
LeaseRef identifies a record and the opaque token for its current lease generation. An expired or replaced token cannot mutate the record.
type MessageState ¶
type MessageState string
MessageState is a durable outbox state accepted by administrative filters.
const ( MessageStatePending MessageState = "pending" MessageStateLeased MessageState = "leased" MessageStateDelivered MessageState = "delivered" MessageStateDead MessageState = "dead" )
type MessageSummary ¶
type MessageSummary struct {
ID string
Topic string
OrderingKey string
IdempotencyKey string
Attempts int
AvailableAt time.Time
CreatedAt time.Time
UpdatedAt time.Time
State MessageState
LeaseOwner *string
LeasedUntil *time.Time
DeliveredAt *time.Time
DeadLetteredAt *time.Time
LastError *string
}
MessageSummary intentionally excludes payload and metadata.
type ReplayRequest ¶
ReplayRequest is an explicit, audited request to make terminal records publishable again. Replaying can produce duplicates and resets attempts.
type SerializationMode ¶
type SerializationMode uint8
SerializationMode scopes claim serialization. Ordering-key mode treats an empty key as unordered; topic mode serializes every record in each topic.
const ( SerializeNone SerializationMode = iota SerializeByOrderingKey SerializeByTopic )
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store coordinates relay state through PostgreSQL.
func NewStore ¶
func NewStore(pool *pgxpool.Pool, config StoreConfig) (*Store, error)
NewStore creates a PostgreSQL relay store.
func (*Store) ArchiveAndPruneDead ¶
func (s *Store) ArchiveAndPruneDead( ctx context.Context, cutoff time.Time, limit int, archiver DeadArchiver, ) (ids []string, err error)
ArchiveAndPruneDead archives a bounded dead-letter batch before deletion.
func (*Store) ArchiveAndPruneDelivered ¶
func (s *Store) ArchiveAndPruneDelivered( ctx context.Context, cutoff time.Time, limit int, archiver Archiver, ) (ids []string, err error)
ArchiveAndPruneDelivered locks a bounded delivered batch, invokes archiver, and deletes those records only after archival succeeds. The database transaction remains open during archival so concurrent maintenance workers cannot select the same rows. An ambiguous commit can archive a batch more than once, so archives must be idempotent by envelope ID.
func (*Store) Backlog ¶
func (s *Store) Backlog(ctx context.Context) (BacklogStats, error)
Backlog returns current state counts and the oldest pending availability time. It is intended for low-frequency health and administrative checks.
func (*Store) Claim ¶
Claim atomically leases available or expired messages. PostgreSQL row locks with SKIP LOCKED make concurrent relay calls return disjoint records.
func (*Store) DeadLetter ¶
DeadLetter moves a leased record to its terminal failure state.
func (*Store) ExtendLease ¶
func (s *Store) ExtendLease(ctx context.Context, lease LeaseRef, duration time.Duration) (time.Time, error)
ExtendLease moves the lease deadline relative to the PostgreSQL clock.
func (*Store) Inspect ¶
func (s *Store) Inspect(ctx context.Context, request InspectRequest) ([]MessageSummary, error)
Inspect returns bounded payload-free summaries for operator tooling.
func (*Store) MarkDelivered ¶
MarkDelivered records publisher success. A publisher success followed by a failure here must be retried and can therefore result in duplicate delivery.
func (*Store) PruneDead ¶
func (s *Store) PruneDead(ctx context.Context, cutoff time.Time, limit int) (ids []string, err error)
PruneDead deletes only dead letters older than cutoff in a bounded batch.
func (*Store) PruneDelivered ¶
func (s *Store) PruneDelivered(ctx context.Context, cutoff time.Time, limit int) (ids []string, err error)
PruneDelivered deletes only delivered records older than cutoff, with a bounded SKIP LOCKED batch so concurrent maintenance workers stay disjoint.
func (*Store) ReleaseLease ¶
ReleaseLease makes a currently owned claim immediately available. It is intended for graceful relay cancellation before publication completes.
type StoreConfig ¶
type StoreConfig struct {
Schema string
Table string
MaxClaimBatch int
MaxAdminBatch int
MaxLeaseDuration time.Duration
LeaseTokenGenerator func() (string, error)
Observer outbox.Observer
Clock func() time.Time
}
StoreConfig bounds relay claims and selects the outbox table.
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer inserts envelopes through caller-owned pgx transactions.
func NewWriter ¶
func NewWriter(config WriterConfig) (*Writer, error)
NewWriter creates a transactional writer. Empty fields select the default public.outbox_messages table.