eventoutbox

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package eventoutbox is a durable, restart-surviving queue of outbound job lifecycle events POSTed to a controller.

It exists because the obvious alternative — fire-and-forget POSTs — loses a terminal event whenever the controller is briefly unreachable, and a lost terminal event leaves the central row stuck "running" forever. Nothing retries it, because nothing recorded that it failed.

Backed by a `pending_events` table on a caller-supplied *sql.DB — the package is driver-agnostic (the agent opens the DB with its own sqlite driver and may share it with other tables). Enqueue persists the event then fires an immediate best-effort push; a drain loop retries the backlog on an interval, oldest-first, bailing on the first failure (the controller is probably down) to retry next tick.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Outbox

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

Outbox is the durable push queue. Construct with New, then Start the drain loop and call Enqueue on every event.

func New

func New(db *sql.DB, client *http.Client, urlFor func(string) string) (*Outbox, error)

New creates the pending_events table on db (idempotent) and returns an Outbox.

The Outbox writes from several goroutines (one push per Enqueue, plus the drain loop) on the caller's *sql.DB, so a SQLite database must be opened with a busy timeout (and WAL), e.g. "file:events.sqlite?_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)" for modernc.org/sqlite. Without it a concurrent reader makes the writer fail with SQLITE_BUSY / "disk I/O error" instead of waiting. urlFor builds the POST URL from an event's job id (e.g. CONTROL_CENTER_URL + "/api/duplicacy/jobs/" + id + "/event"). client should already carry any auth (e.g. a bearer round-tripper).

func (*Outbox) Close

func (o *Outbox) Close()

Close stops the drain loop and waits for it to exit. Does not close the *sql.DB (the caller owns it).

func (*Outbox) Enqueue

func (o *Outbox) Enqueue(jobID, event string, payload []byte)

Enqueue durably persists an event then fires an immediate best-effort push in a detached goroutine. On push failure the row stays for the drain loop.

func (*Outbox) Start

func (o *Outbox) Start(ctx context.Context)

Start runs the drain loop in a tracked goroutine until ctx is cancelled or Close is called.

Jump to

Keyboard shortcuts

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