The lib-owned checkpoint store (spec §7) for non-transactional sinks. A GenServer
over a normal Postgrex connection that owns one replicant_checkpoints row per
slot and reads/writes commit_lsn behind the value-free boundary (Critical Rule
1 — the store carries slot_name + LSN only; a Postgrex fault is scrubbed to a
structural %Replicant.Error{}, never echoing a parameter).
The connection uses a non-sync connect so a transient store blip at boot does
not fail the :temporary pipeline (Postgrex reconnects in the background); a
genuine outage surfaces as a query fault that halts fail-closed. The table is
created + shape-probed lazily on the first read/write (once), so init/1 never
blocks on the DB.
Summary
Functions
Returns a specification to start this module under a supervisor.
Default max_retries when :checkpoint_store omits it (spec §6).
Default retry_backoff_ms when :checkpoint_store omits it (spec §6).
Emit the value-free [:replicant, :checkpoint_store, :retrying] event (slot_name + ints only).
True when a store fault reason is PERMANENT (retrying cannot fix it): a wrong
pre-existing column type (:checkpoint_store_schema_mismatch) or an invalid table
identifier (:config_invalid). Every other reason — :checkpoint_store_failed, into
which a %Postgrex.Error{} / %DBConnection.ConnectionError{} is scrubbed — is
transient AT THE VALUE-FREE BOUNDARY (a momentary blip and a wrong-host misconfig are
indistinguishable here), so it is retried, then halted (spec §7).
Read the durable checkpoint for this slot (nil = never written) or a value-free error.
The shared retry decision: :retry while attempt < max_retries, else :halt.
attempt is the count of retries ALREADY made (0 on the first fault). max_retries: 0
⇒ always :halt (halt-now opt-out). Used identically by the connect-read (timer) and
mid-stream write (sleep) sites so their counter semantics cannot drift (spec §4).
The Registry via-name a pipeline's CheckpointStore registers under.
Write the checkpoint (INSERT ... ON CONFLICT) or return a value-free error. Never advance the ack on {:error, _}.
Functions
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec default_max_retries() :: non_neg_integer()
Default max_retries when :checkpoint_store omits it (spec §6).
@spec default_retry_backoff_ms() :: pos_integer()
Default retry_backoff_ms when :checkpoint_store omits it (spec §6).
@spec emit_retrying(String.t(), pos_integer(), non_neg_integer()) :: :ok
Emit the value-free [:replicant, :checkpoint_store, :retrying] event (slot_name + ints only).
True when a store fault reason is PERMANENT (retrying cannot fix it): a wrong
pre-existing column type (:checkpoint_store_schema_mismatch) or an invalid table
identifier (:config_invalid). Every other reason — :checkpoint_store_failed, into
which a %Postgrex.Error{} / %DBConnection.ConnectionError{} is scrubbed — is
transient AT THE VALUE-FREE BOUNDARY (a momentary blip and a wrong-host misconfig are
indistinguishable here), so it is retried, then halted (spec §7).
@spec read(GenServer.server()) :: {:ok, Replicant.lsn() | nil} | {:error, Replicant.Error.t()}
Read the durable checkpoint for this slot (nil = never written) or a value-free error.
@spec retry_decision(non_neg_integer(), non_neg_integer()) :: :retry | :halt
The shared retry decision: :retry while attempt < max_retries, else :halt.
attempt is the count of retries ALREADY made (0 on the first fault). max_retries: 0
⇒ always :halt (halt-now opt-out). Used identically by the connect-read (timer) and
mid-stream write (sleep) sites so their counter semantics cannot drift (spec §4).
@spec start_link(keyword()) :: GenServer.on_start()
The Registry via-name a pipeline's CheckpointStore registers under.
@spec write(GenServer.server(), Replicant.lsn()) :: :ok | {:error, Replicant.Error.t()}
Write the checkpoint (INSERT ... ON CONFLICT) or return a value-free error. Never advance the ack on {:error, _}.