Documentation
¶
Overview ¶
Package idem is exactly-once request execution over a per-org SQLite database: a request named by a caller-supplied idempotency key runs AT MOST ONCE, and any retry — including one re-routed to a different replica after a rolling upgrade — returns the first run's recorded result instead of executing the effect again.
It is the request-layer generalization of visor's insert-once MeterLease (object/meter_lease.go): the key is the PRIMARY KEY of a row written IN THE SAME TRANSACTION as the effect, so the dedup record and the effect commit atomically — either both land or neither. There is no window in which the effect is applied but the key is unrecorded (which would allow a re-run), nor one in which the key is recorded but the effect is missing (which would wrongly suppress a run).
Exactly-once across a writer handoff ¶
The row lives in the per-org SQLite the HA substrate snapshots to the object store, so the dedup record SHIPS WITH THE DATA. A successor that hydrates the latest fenced snapshot before it serves (hydrate-before-write) therefore sees every acknowledged request's key and refuses to re-run it. Exactly-once across a handoff is two composed properties, neither sufficient alone:
fenced ship-before-ack : a request is 'done' only once its effect is durably
in the fenced object store; a FENCED ship means the
request FAILED and the caller retries (never acks).
dedup key in the WAL : the successor hydrates the shipped snapshot, so a
retry of an acknowledged request finds its key present.
This package owns only the first-writer-wins dedup + result recall. The fenced ship (github.com/hanzoai/vfs/replica.FencedStore) and the single-writer gate + hydrate (internal/org) are its composition partners, each in its own lane.
Index ¶
- Variables
- func Applied(ctx context.Context, db *sql.DB, key string) (result []byte, done bool, err error)
- func EnsureSchema(ctx context.Context, db *sql.DB) error
- func Once(ctx context.Context, db *sql.DB, key string, round uint64, ...) (result []byte, applied bool, err error)
- func Prune(ctx context.Context, db *sql.DB, cutoff time.Time) (int64, error)
Constants ¶
This section is empty.
Variables ¶
var ErrAlreadyApplied = errors.New("idem: request already applied")
ErrAlreadyApplied reports that key was executed by a prior call. It is the 'fail if already done' signal: Once returns it (with the stored result) instead of running the effect a second time. Callers that want idempotent success return the result and swallow this; callers that want a hard 'duplicate' error surface it. errors.Is(err, ErrAlreadyApplied) distinguishes it from a real failure.
Functions ¶
func Applied ¶
Applied reports whether key has already been executed, returning the stored result — the read-only 'fail if already done' check for a caller that wants to short-circuit before doing any work.
func EnsureSchema ¶
EnsureSchema creates the idempotency table if absent. Safe to call repeatedly; Once calls it, so callers rarely need to.
func Once ¶
func Once(ctx context.Context, db *sql.DB, key string, round uint64, apply func(context.Context, *sql.Tx) ([]byte, error)) (result []byte, applied bool, err error)
Once runs apply EXACTLY ONCE for key against db and records the outcome.
On the FIRST call for key: it opens a transaction, inserts the key row, runs apply WITHIN that same transaction, stores apply's result bytes, and commits — so the dedup row and every effect apply performed (which apply MUST perform through the provided *sql.Tx, or atomicity is lost) land together. It returns (result, true, nil).
On any LATER call for the same key: apply is NOT run; Once returns the stored result with applied=false and ErrAlreadyApplied wrapped in err. round is recorded alongside the row (the fencing round under which the request was first applied) for audit; it does not affect dedup.
Types ¶
This section is empty.