Skip to main content

SyncDelegate

Trait SyncDelegate 

Source
pub trait SyncDelegate:
    Send
    + Sync
    + 'static {
Show 73 methods // Required methods fn sync_identity(&self) -> LiteIdentity; fn regenerate_identity<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn rotate_peer_id<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn pending_deltas(&self) -> Vec<PendingDelta>; fn set_pending_delta_seq<'life0, 'async_trait>( &'life0 self, mutation_id: u64, seq: u64, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn acknowledge(&self, mutation_id: u64); fn reject(&self, mutation_id: u64); fn reject_with_policy(&self, mutation_id: u64, hint: &CompensationHint); fn import_remote(&self, collection: &str, data: &[u8]); fn apply_remote_row<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 RowPushMsg, ) -> Pin<Box<dyn Future<Output = Result<(), NodeDbError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn import_definition<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 DefinitionSyncMsg, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn import_collection_schema<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 CollectionSchemaSyncMsg, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn handle_array_delta<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 ArrayDeltaMsg, ) -> Pin<Box<dyn Future<Output = Option<ArrayAckMsg>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn handle_array_delta_batch<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 ArrayDeltaBatchMsg, ) -> Pin<Box<dyn Future<Output = Option<ArrayAckMsg>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn handle_array_reject<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 ArrayRejectMsg, ) -> Pin<Box<dyn Future<Output = Option<ArrayCatchupRequestMsg>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn handle_array_snapshot<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 ArraySnapshotMsg, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn handle_array_snapshot_chunk<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 ArraySnapshotChunkMsg, ) -> Pin<Box<dyn Future<Output = Option<ArrayAckMsg>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn begin_array_catchup(&self) -> Vec<ArrayCatchupRequestMsg>; fn pending_array_ops<'life0, 'async_trait>( &'life0 self, after: Option<Hlc>, limit: usize, ) -> Pin<Box<dyn Future<Output = Result<Vec<PendingArrayOp>, LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn persist_array_op_seq<'life0, 'life1, 'async_trait>( &'life0 self, op: &'life1 PendingArrayOp, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn retire_array_ops<'life0, 'life1, 'async_trait>( &'life0 self, hlcs: &'life1 [Hlc], ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn array_schema_announce( &self, array: &str, ) -> Result<Option<ArraySchemaSyncMsg>, LiteError>; fn pending_columnar_batches<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Vec<(Vec<u8>, PendingColumnarBatch)>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn mark_columnar_batch_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn ack_columnar_batch_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn acknowledge_columnar_batch<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn pending_vector_inserts<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Vec<(Vec<u8>, PendingVectorInsert)>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn mark_vector_insert_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn ack_vector_insert_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn acknowledge_vector_insert<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn pending_vector_deletes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Vec<(Vec<u8>, PendingVectorDelete)>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn mark_vector_delete_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn ack_vector_delete_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn acknowledge_vector_delete<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn pending_fts_indexes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<(Vec<u8>, PendingFtsIndex)>, LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn mark_fts_index_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn ack_fts_index_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn acknowledge_fts_index<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn pending_fts_deletes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<(Vec<u8>, PendingFtsDelete)>, LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn mark_fts_delete_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn ack_fts_delete_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn acknowledge_fts_delete<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn pending_spatial_inserts<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Vec<(Vec<u8>, PendingSpatialInsert)>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn mark_spatial_insert_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn ack_spatial_insert_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn acknowledge_spatial_insert<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn pending_spatial_deletes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Vec<(Vec<u8>, PendingSpatialDelete)>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn mark_spatial_delete_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn ack_spatial_delete_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn acknowledge_spatial_delete<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn pending_timeseries_batches<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Vec<(Vec<u8>, PendingTimeseriesBatch)>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn mark_timeseries_batch_in_flight<'life0, 'async_trait>( &'life0 self, stream_seq: u64, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn ack_timeseries_batches_through_seq<'life0, 'async_trait>( &'life0 self, applied_seq: u64, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn ack_timeseries_batch_by_id<'life0, 'async_trait>( &'life0 self, batch_id: u64, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn acknowledge_timeseries_batch<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn pending_kv_writes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<(Vec<u8>, PendingKvWrite)>, LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn persist_kv_write_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], write: &'life2 PendingKvWrite, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn mark_kv_write_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn retire_kv_write<'life0, 'async_trait>( &'life0 self, batch_id: u64, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn persist_columnar_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], batch: &'life2 PendingColumnarBatch, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn persist_timeseries_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], batch: &'life2 PendingTimeseriesBatch, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn persist_vector_insert_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], insert: &'life2 PendingVectorInsert, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn persist_vector_delete_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], delete: &'life2 PendingVectorDelete, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn persist_fts_index_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], entry: &'life2 PendingFtsIndex, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn persist_fts_delete_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], entry: &'life2 PendingFtsDelete, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn persist_spatial_insert_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], insert: &'life2 PendingSpatialInsert, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn persist_spatial_delete_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], delete: &'life2 PendingSpatialDelete, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn clear_engine_in_flight<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn persist_producer_state<'life0, 'async_trait>( &'life0 self, producer_id: u64, accepted_epoch: u64, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn load_producer_state<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = (u64, u64)> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn next_stream_seq<'life0, 'async_trait>( &'life0 self, stream_id: u64, ) -> Pin<Box<dyn Future<Output = u64> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn record_stream_ack<'life0, 'async_trait>( &'life0 self, stream_id: u64, applied_seq: u64, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn get_collection_meta<'life0, 'life1, 'async_trait>( &'life0 self, name: &'life1 str, ) -> Pin<Box<dyn Future<Output = Option<CollectionMeta>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait;
}
Expand description

Callback interface for the sync runner to read/write pending deltas from the owning NodeDbLite. This avoids the runner owning the database.

Runtime contract: All methods are called from inside a Tokio runtime (via run_sync_loop). Implementations MUST NOT use tokio::task::block_in_place to call &self async methods — that pattern panics on current_thread runtimes and is exactly what this trait was redesigned to avoid. Async work (e.g. persisting a synced function definition to storage) belongs on import_definition, which is async fn for that reason. Sync methods that touch only in-memory state may stay sync.

Required Methods§

Source

fn sync_identity(&self) -> LiteIdentity

This instance’s durable identity: lite_id, epoch, and the Loro peer id local operations are authored under.

Read for every frame rather than cached by the transport. All three change while a session is alive — a peer_id_collision refusal rotates the peer id, a reported fork replaces the whole identity — and a frame stamped from a stale copy carries exactly the identity Origin refused.

Source

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

Replace this instance’s producer identity after Origin reports a fork, re-authoring local state under it.

Async because it persists the new identity and flushes the rebuilt documents; a rotation that is not durable resumes the forked identity on the next open.

Source

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

Adopt a new Loro peer id after Origin refuses the current one as another replica’s, re-authoring local state under it.

Source

fn pending_deltas(&self) -> Vec<PendingDelta>

Get all pending CRDT deltas to push to Origin.

Source

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

Assign a stable stream seq to a pending CRDT delta (first-send only).

No-op if the delta already has a non-zero seq, so the same seq is reused on reconnect re-sends and Origin can deduplicate.

Source

fn acknowledge(&self, mutation_id: u64)

Acknowledge deltas up to the given mutation_id.

Source

fn reject(&self, mutation_id: u64)

Reject a specific delta (rollback optimistic state).

Source

fn reject_with_policy(&self, mutation_id: u64, hint: &CompensationHint)

Reject a delta with policy-aware resolution. Consults the PolicyRegistry before deciding how to handle the rejection.

Source

fn import_remote(&self, collection: &str, data: &[u8])

Import remote deltas from Origin into collection’s local CRDT state.

The collection travels with the update because each collection has its own Loro document; the update bytes alone do not identify the target.

Source

fn apply_remote_row<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 RowPushMsg, ) -> Pin<Box<dyn Future<Output = Result<(), NodeDbError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Apply a server-originated row post-image (opcode 0x15).

Distinct from Self::import_remote, which takes Loro update bytes. Origin sends this for writes with no client-authored CRDT operation to replicate — SQL DML, and DDL-managed system rows such as retention policies and alerts — carrying the row’s full post-image (or, for a delete, an empty payload and RowOp::Delete).

A KV collection’s post-image is the {key, value…} row every KV read returns. A payload that is not a row map is a serialization error, and nothing is applied.

Async because applying the row writes through to local storage.

Source

fn import_definition<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 DefinitionSyncMsg, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Import a definition sync message (function/trigger/procedure) from Origin. Async because persisting the definition to storage involves KV store writes through spawn_blocking.

Source

fn import_collection_schema<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 CollectionSchemaSyncMsg, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Materialize a collection announced by a sync peer (opcode 0x13).

Create-if-absent registers the collection from the descriptor and persists authoritative metadata so the SQL catalog surfaces the real engine, bitemporal flag, and columns. Async because it performs storage reads/writes. Errors are logged and swallowed at the impl boundary so a bad announcement never kills the sync session.

Source

fn handle_array_delta<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 ArrayDeltaMsg, ) -> Pin<Box<dyn Future<Output = Option<ArrayAckMsg>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Apply a single ArrayDelta frame from Origin.

An applied or already-present op advances the array’s catch-up high-water mark to its HLC. Returns the ArrayAckMsg to send back to Origin (advancing its GC frontier), or None if the frame was already applied (idempotent) or rejected (logged as a warning).

Async because recording the high-water mark writes to storage.

Source

fn handle_array_delta_batch<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 ArrayDeltaBatchMsg, ) -> Pin<Box<dyn Future<Output = Option<ArrayAckMsg>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Apply a batch of ArrayDelta frames from Origin.

Applies each op in order. The catch-up high-water mark advances to the last op before the first rejected op, so a rejected op is asked for again on the next catch-up. Returns the ArrayAckMsg for the highest HLC applied (or None if the batch was empty or all ops were idempotent/rejected).

Source

fn handle_array_reject<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 ArrayRejectMsg, ) -> Pin<Box<dyn Future<Output = Option<ArrayCatchupRequestMsg>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Process an ArrayReject from Origin.

Applies the reason’s RejectDisposition: a Drop removes the op from the pending queue, and every other disposition keeps it. For RetentionFloor, persists the array’s catch-up flag and returns the catch-up request to send: it starts at Hlc::ZERO, so Origin answers with a snapshot. Returns None for every other reason.

Source

fn handle_array_snapshot<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 ArraySnapshotMsg, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Buffer an ArraySnapshot header from Origin. Errors are logged.

Source

fn handle_array_snapshot_chunk<'life0, 'life1, 'async_trait>( &'life0 self, msg: &'life1 ArraySnapshotChunkMsg, ) -> Pin<Box<dyn Future<Output = Option<ArrayAckMsg>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Buffer an ArraySnapshotChunk from Origin.

On the last chunk the snapshot is assembled and applied: the array’s catch-up flag is cleared, its high-water mark advances to the snapshot HLC, and the ArrayAckMsg carrying that HLC is returned. Returns None while chunks remain. An assembly or apply error is logged and flags the array, so the next session asks for a snapshot again.

Source

fn begin_array_catchup(&self) -> Vec<ArrayCatchupRequestMsg>

Start the array catch-up round for a newly connected session.

Returns one ArrayCatchupRequestMsg per array this replica holds, each starting at the array’s catch-up high-water mark (or Hlc::ZERO when flagged for a snapshot). Drops partial snapshot assemblies from the previous session. Returns an empty list when no arrays exist.

Source

fn pending_array_ops<'life0, 'async_trait>( &'life0 self, after: Option<Hlc>, limit: usize, ) -> Pin<Box<dyn Future<Output = Result<Vec<PendingArrayOp>, LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Up to limit queued local array ops with an HLC strictly greater than after, in HLC order. None starts at the head of the queue.

Source

fn persist_array_op_seq<'life0, 'life1, 'async_trait>( &'life0 self, op: &'life1 PendingArrayOp, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Persist op.seq into the queued op before its first send.

On an error the caller does not send, and the op waits for a later tick.

Source

fn retire_array_ops<'life0, 'life1, 'async_trait>( &'life0 self, hlcs: &'life1 [Hlc], ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Remove the queued array ops named in hlcs: ops Origin applied, and ops the push loop cannot encode. Ops no longer queued are skipped.

Source

fn array_schema_announce( &self, array: &str, ) -> Result<Option<ArraySchemaSyncMsg>, LiteError>

The ArraySchema body announcing array’s current schema to Origin: the schema HLC and Loro snapshot, read together. Returns None when array has no local schema.

Source

fn pending_columnar_batches<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Vec<(Vec<u8>, PendingColumnarBatch)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Drain up to PUSH_DRAIN_LIMIT pending batches from durable storage, skipping any currently in-flight entries.

Returns (durable_key, batch) pairs. On successful send, call mark_columnar_batch_in_flight. The durable entry is deleted only when Origin’s ack arrives via ack_columnar_batch_in_flight.

Source

fn mark_columnar_batch_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Record that a columnar batch has been sent and is awaiting Origin ack.

Source

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

On Origin ack: remove in-flight record and delete the durable entry.

Source

fn acknowledge_columnar_batch<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Delete the durable entry for a confirmed batch directly (used for un-encodable entries that must be discarded at send time).

Source

fn pending_vector_inserts<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Vec<(Vec<u8>, PendingVectorInsert)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Drain up to PUSH_DRAIN_LIMIT pending insert entries, skipping in-flight.

Source

fn mark_vector_insert_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Record that a vector insert has been sent and is awaiting Origin ack.

Source

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

On Origin ack: remove in-flight record and delete the durable entry.

Source

fn acknowledge_vector_insert<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Delete the durable insert entry directly (for un-encodable entries).

Source

fn pending_vector_deletes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Vec<(Vec<u8>, PendingVectorDelete)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Drain up to PUSH_DRAIN_LIMIT pending delete entries, skipping in-flight.

Source

fn mark_vector_delete_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Record that a vector delete has been sent and is awaiting Origin ack.

Source

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

On Origin ack: remove in-flight record and delete the durable entry.

Source

fn acknowledge_vector_delete<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Delete the durable delete entry directly (for un-encodable entries).

Source

fn pending_fts_indexes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<(Vec<u8>, PendingFtsIndex)>, LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Drain up to PUSH_DRAIN_LIMIT pending index entries, skipping in-flight.

Source

fn mark_fts_index_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Record that an FTS index entry has been sent and is awaiting Origin ack.

Source

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

On Origin ack: remove in-flight record and delete the durable entry.

Source

fn acknowledge_fts_index<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Delete the durable index entry directly (for un-encodable entries).

Source

fn pending_fts_deletes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<(Vec<u8>, PendingFtsDelete)>, LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Drain up to PUSH_DRAIN_LIMIT pending FTS delete entries, skipping in-flight.

Source

fn mark_fts_delete_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Record that an FTS delete entry has been sent and is awaiting Origin ack.

Source

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

On Origin ack: remove in-flight record and delete the durable entry.

Source

fn acknowledge_fts_delete<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Delete the durable delete entry directly (for un-encodable entries).

Source

fn pending_spatial_inserts<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Vec<(Vec<u8>, PendingSpatialInsert)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Drain up to PUSH_DRAIN_LIMIT pending insert entries, skipping in-flight.

Source

fn mark_spatial_insert_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Record that a spatial insert has been sent and is awaiting Origin ack.

Source

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

On Origin ack: remove in-flight record and delete the durable entry.

Source

fn acknowledge_spatial_insert<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Delete the durable insert entry directly (for un-encodable entries).

Source

fn pending_spatial_deletes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Vec<(Vec<u8>, PendingSpatialDelete)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Drain up to PUSH_DRAIN_LIMIT pending spatial delete entries, skipping in-flight.

Source

fn mark_spatial_delete_in_flight<'life0, 'async_trait>( &'life0 self, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Record that a spatial delete has been sent and is awaiting Origin ack.

Source

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

On Origin ack: remove in-flight record and delete the durable entry.

Source

fn acknowledge_spatial_delete<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Delete the durable delete entry directly (for un-encodable entries).

Source

fn pending_timeseries_batches<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Vec<(Vec<u8>, PendingTimeseriesBatch)>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Drain up to PUSH_DRAIN_LIMIT pending batches, skipping in-flight entries.

Source

fn mark_timeseries_batch_in_flight<'life0, 'async_trait>( &'life0 self, stream_seq: u64, batch_id: u64, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Record that a timeseries batch has been sent and is awaiting Origin ack.

Indexed by stream_seq for the cumulative applied_seq success path, and carrying batch_id so a terminally rejected batch — which never advances that frontier — can still be named and retired.

Source

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

On Origin ack: delete all durable entries whose seq ≤ applied_seq.

Source

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

On terminal rejection: delete the durable entry for exactly batch_id.

Required alongside the sweep above because a rejected batch’s seq sits above applied_seq (it never applied), so the cumulative path can never retire it and the push loop would re-send it indefinitely.

Source

fn acknowledge_timeseries_batch<'life0, 'async_trait>( &'life0 self, durable_key: Vec<u8>, ) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Delete the durable entry directly (for empty/un-encodable batches).

Source

fn pending_kv_writes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<(Vec<u8>, PendingKvWrite)>, LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Up to PUSH_DRAIN_LIMIT pending KV writes in queue order, skipping the ones in flight. Returns (durable_key, write) pairs.

Source

fn persist_kv_write_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], write: &'life2 PendingKvWrite, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Persist the seq assigned to the KV write stored under key.

Called before the frame is sent. On an error the caller does not send, and the write waits for the next tick.

Source

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

Record that the KV write with batch_id was sent and awaits its ack.

Source

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

Retire the KV write with batch_id after Origin’s final answer: forget it is in flight and delete its durable entry.

Source

fn persist_columnar_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], batch: &'life2 PendingColumnarBatch, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Persist an assigned stream seq into the durable columnar entry at key.

Must be called before sending the frame. If this returns an error the caller must NOT send — it should retain the entry for the next drain tick.

Source

fn persist_timeseries_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], batch: &'life2 PendingTimeseriesBatch, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Persist an assigned stream seq into the durable timeseries entry at key.

Source

fn persist_vector_insert_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], insert: &'life2 PendingVectorInsert, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Persist an assigned stream seq into the durable vector insert entry at key.

Source

fn persist_vector_delete_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], delete: &'life2 PendingVectorDelete, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Persist an assigned stream seq into the durable vector delete entry at key.

Source

fn persist_fts_index_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], entry: &'life2 PendingFtsIndex, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Persist an assigned stream seq into the durable FTS index entry at key.

Source

fn persist_fts_delete_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], entry: &'life2 PendingFtsDelete, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Persist an assigned stream seq into the durable FTS delete entry at key.

Source

fn persist_spatial_insert_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], insert: &'life2 PendingSpatialInsert, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Persist an assigned stream seq into the durable spatial insert entry at key.

Source

fn persist_spatial_delete_seq<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 [u8], delete: &'life2 PendingSpatialDelete, ) -> Pin<Box<dyn Future<Output = Result<(), LiteError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Persist an assigned stream seq into the durable spatial delete entry at key.

Source

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

Clear all engine in-flight maps on reconnect.

The durable entries are still in storage and will be re-drained on the next push tick. Origin’s idempotent gate deduplicates re-sent batches.

Source

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

Durably persist the server-assigned producer_id and accepted_epoch so they survive process restart and can be reloaded on reconnect.

Called after every successful handshake acknowledgement.

Source

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

Load the last-persisted producer_id and accepted_epoch.

Returns (0, 0) if no state has been persisted yet (first run). Called at the start of each connection attempt so the client has its identity available before the outbound handshake is built.

Source

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

Assign the next monotonic sequence number for the given stream_id.

Delegates to StreamSeqTracker::next_seq which persists before returning (persist-before-send invariant). On storage error, logs a warning and returns 0 — a zero seq applies unconditionally on Origin, so this is safe degradation with no data loss.

Source

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

Record that Origin has applied applied_seq for stream_id.

Delegates to StreamSeqTracker::record_ack. Errors are logged and ignored — the last_assigned frontier already prevents re-sending un-acked seqs, so this is a refinement of the acknowledged frontier.

Source

fn get_collection_meta<'life0, 'life1, 'async_trait>( &'life0 self, name: &'life1 str, ) -> Pin<Box<dyn Future<Output = Option<CollectionMeta>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Look up a collection’s persisted metadata by name, for building the outbound CollectionSchema (opcode 0x13) announce sent before a collection’s first CRDT delta in a sync session.

Returns None if the collection has no explicitly persisted metadata (e.g. an implicit CRDT-only collection created without DDL) — the caller skips announcing it and lets Origin infer a schemaless collection from the first delta, matching pre-announce behavior.

Dyn Compatibility§

This trait is dyn compatible.

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

Implementors§