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:
livestreams ongoing changes, resuming from the mechanism’s own durable position (a replication slot’sconfirmed_flush_lsn, a poll cursor, …). No position is threaded through this API — resume state is the mechanism’s to own.snapshotreads 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§
Provided Methods§
Sourcefn 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 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.
Sourcefn lag<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<Option<u64>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: '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,
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".