pub trait KeyedCheckpointStore: Send + Sync {
// Required methods
fn load_checkpoint(
&self,
key: CheckpointKey,
) -> Result<Option<u64>, StoreError>;
fn record_checkpoint(
&self,
key: CheckpointKey,
block: u64,
) -> Result<(), StoreError>;
// Provided method
fn flush_checkpoint(&self, key: CheckpointKey) -> Result<(), StoreError> { ... }
}Expand description
Durable high-water marks of the last block each on-chain watcher scanned,
keyed by CheckpointKey (#751, generalized in #1092/#1108). Persisting
them across restarts is what lets a watcher’s bring-up backfill cover the
downtime gap: an event landing while the node is down sits in a block
before the next boot’s head, so without a persisted floor a head-anchored
backfill never sees it. On boot the watcher backfills from the stored block
(minus a small reorg margin) up to head; the per-log sinks are idempotent, so
re-scanning the overlap is harmless.
A directly disk-backed implementation MUST commit durably (fsync) before
returning Ok from record_checkpoint. A debouncing decorator MAY relax
that per-call fsync — buffering in memory and coarsening the durable write
cadence — provided it preserves the two invariants this contract rests on,
per key: the persisted block is monotonic (never lowered) and the
latest buffered block is forced out on graceful shutdown via
flush_checkpoint. Both relaxations
are safe because a lost or lagging checkpoint only ever silently widens the
rescan (more RPC), never narrows it.
Required Methods§
Sourcefn load_checkpoint(&self, key: CheckpointKey) -> Result<Option<u64>, StoreError>
fn load_checkpoint(&self, key: CheckpointKey) -> Result<Option<u64>, StoreError>
The last block scanned for key, or None on a never-written key
(first-ever boot for that watcher — the caller applies its configured
none-fallback floor).
§Errors
Returns a StoreError if the backing store is unreadable.
Sourcefn record_checkpoint(
&self,
key: CheckpointKey,
block: u64,
) -> Result<(), StoreError>
fn record_checkpoint( &self, key: CheckpointKey, block: u64, ) -> Result<(), StoreError>
Persist the last block scanned for key. Overwrites the prior value.
Called as each backfill window and live tick advances, so the next boot
resumes from here.
A debouncing decorator MAY buffer the value in memory and defer the
durable write to a coarser cadence (the floor only ever lags the true
scan position, which is safe — see the type-level contract above); such a
decorator overrides flush_checkpoint to force
the buffered value out on graceful shutdown. A directly disk-backed
implementation commits durably before returning Ok.
§Errors
Returns a StoreError if the durable write fails.
Provided Methods§
Sourcefn flush_checkpoint(&self, key: CheckpointKey) -> Result<(), StoreError>
fn flush_checkpoint(&self, key: CheckpointKey) -> Result<(), StoreError>
Force any buffered checkpoint for key to durable storage. The default
is a no-op: implementations that already commit durably inside
record_checkpoint have nothing buffered. A
debouncing decorator overrides this to fsync the latest deferred block,
and the runtime calls it on graceful shutdown so the most recent scan
progress is not lost to the next boot’s rescan.
§Errors
Returns a StoreError if the durable write fails.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".