Skip to main content

ChangeCapture

Trait ChangeCapture 

Source
pub trait ChangeCapture:
    Debug
    + Send
    + Sync {
    // Required method
    fn live<'life0, 'async_trait>(
        &'life0 self,
    ) -> Pin<Box<dyn Future<Output = Result<BoxStream<'static, Result<Change>>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;

    // Provided methods
    fn snapshot<'life0, 'life1, 'async_trait>(
        &'life0 self,
        tables: &'life1 [SnapshotTable],
    ) -> Pin<Box<dyn Future<Output = Result<BoxStream<'static, Result<Change>>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait { ... }
    fn lag<'life0, 'async_trait>(
        &'life0 self,
    ) -> Pin<Box<dyn Future<Output = Result<Option<u64>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait { ... }
}
Expand description

A pluggable change-capture mechanism — logical replication (WAL) today, polling or trigger-based capture later.

The mechanism exposes two independent capabilities; the engine decides when to use each:

  • live streams ongoing changes, resuming from the mechanism’s own durable position (a replication slot’s confirmed_flush_lsn, a poll cursor, …). No position is threaded through this API — resume state is the mechanism’s to own.
  • snapshot reads the current rows of a set of tables as a finite stream — the data an initial backfill needs. Whether a backfill is needed is not the mechanism’s call: the engine asks the sink whether a target is already seeded and only then requests a snapshot. A mechanism that cannot snapshot keeps the default (an empty stream).

Each emitted Change carries an Ack; for live, the mechanism only advances its durable resume point once changes are confirmed, which makes delivery at-least-once across restarts. Snapshot changes are not resumable (a crashed backfill simply re-runs, idempotently), so their acks need not move any cursor.

Returned streams are 'static and Send: an implementation moves whatever it needs (its connection, its AckSink) into the stream rather than borrowing from self.

Required Methods§

Source

fn live<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<BoxStream<'static, Result<Change>>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Connect, ensure setup, resume from the last confirmed point, and stream live changes.

Provided Methods§

Source

fn snapshot<'life0, 'life1, 'async_trait>( &'life0 self, tables: &'life1 [SnapshotTable], ) -> Pin<Box<dyn Future<Output = Result<BoxStream<'static, Result<Change>>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Snapshot the current rows of tables as a finite stream of Upsert changes — the rows to seed an index with. The stream ends when the snapshot is complete; there is no in-band boundary marker.

The default is an empty stream, for mechanisms that cannot snapshot.

Source

fn lag<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Option<u64>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

How far the mechanism’s durable resume point trails the source’s latest position, in bytes — e.g. a replication slot’s distance from the server’s current WAL LSN. A growing value means the consumer is falling behind the source; it is the single best signal of pipeline health.

This is sampled out-of-band (by a supervisor, on a timer), not on the change path, so it opens its own short-lived connection rather than borrowing the live stream’s. The default is Ok(None) — for mechanisms that have no notion of lag (e.g. a finite snapshot-only source).

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§