59 lines
2.5 KiB
Rust
59 lines
2.5 KiB
Rust
//! The durable stream subscription receiver (ADR-008 §8; ADR-021 §5;
|
|
//! ADR-019 §6).
|
|
//!
|
|
//! Explicit saves only — no `save_every`, no save-on-drop (the
|
|
//! auto-checkpoint ambiguity is not inherited); checkpointing is the
|
|
//! consumer's call.
|
|
|
|
use crate::Result;
|
|
use crate::future::BoxedFuture;
|
|
use crate::stream::StreamEvent;
|
|
|
|
/// The durable stream subscription handle `StreamHandle::subscribe`
|
|
/// returns.
|
|
///
|
|
/// # Close and error arms (ADR-021 §5)
|
|
///
|
|
/// `recv()`'s `Err` arm carries `Database` only — payloads cross
|
|
/// raw, and `Codec` lives at `payload_as<T>` on the yielded
|
|
/// [`StreamEvent`]; `Closed` is the `None` arm by construction. Close
|
|
/// is terminal; what causes it is the documented engine asymmetry
|
|
/// (SQLite: watcher death; Postgres: engine shutdown — reconnect
|
|
/// wakes arrive on the receiver). A closed receiver never reopens;
|
|
/// recovery is a fresh `subscribe(consumer)` resuming from the saved
|
|
/// offset. No `recv_timeout` exists here — deliberate absence (a
|
|
/// stream consumer's steady state is wake-driven re-read; polling
|
|
/// needs are served by `try_recv` and the offset-anchored
|
|
/// `read_since`).
|
|
pub trait EventReceiver: Send {
|
|
/// Wait for the next event. `None` = the stream receiver closed
|
|
/// (terminal). `Some(Err(...))` carries `Database` only.
|
|
fn recv<'a>(&'a mut self) -> BoxedFuture<'a, Option<Result<StreamEvent>>>;
|
|
|
|
/// Poll without waiting. `Ok(None)` = no event pending right now;
|
|
/// `Err` carries `Database` or `Closed` (closed source).
|
|
fn try_recv(&mut self) -> Result<Option<StreamEvent>>;
|
|
|
|
/// Offset-anchored read from the stream, independent of this
|
|
/// receiver's position (saved checkpoints do not gate reads —
|
|
/// replay is a read concern).
|
|
fn read_since<'a>(
|
|
&'a mut self,
|
|
offset: i64,
|
|
limit: i64,
|
|
) -> BoxedFuture<'a, Result<Vec<StreamEvent>>>;
|
|
|
|
/// Checkpoint the last-yielded event's offset through the same
|
|
/// monotone op the direct `save_offset` form uses — the forms
|
|
/// interleave freely and cannot regress one another (ADR-019 §6).
|
|
/// A save before any event has been yielded is a no-op (the
|
|
/// stored checkpoint untouched). The `Err` arm carries `Database`
|
|
/// only (ADR-021 §5).
|
|
fn save_offset(&mut self) -> Result<()>;
|
|
|
|
/// The receiver's current offset (the last-yielded event's
|
|
/// offset), used when a consumer wants to interleave the direct
|
|
/// save form with the receiver's position.
|
|
fn offset(&self) -> i64;
|
|
}
|