idem

package
v1.801.471 Latest Latest
Warning

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

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

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

Constants

This section is empty.

Variables

View Source
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

func Applied(ctx context.Context, db *sql.DB, key string) (result []byte, done bool, err error)

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

func EnsureSchema(ctx context.Context, db *sql.DB) error

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.

func Prune

func Prune(ctx context.Context, db *sql.DB, cutoff time.Time) (int64, error)

Prune deletes dedup rows first applied before cutoff. Best-effort retention control: prune only keys older than the longest window in which a retry can still arrive, or a legitimately-retried old request would re-execute. Returns the number of rows removed.

Types

This section is empty.

Jump to

Keyboard shortcuts

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