hypercall_db/traits/replay.rs
1//! Journal replay persistence traits (read-only).
2//!
3//! No writer counterpart -- journal writes go through JournalWriter which is
4//! already extracted into `engine_journal.rs`. These queries are used during
5//! engine startup to replay commands/events from the DB after a snapshot load.
6
7use anyhow::Result;
8
9use crate::{PortfolioReplayEvent, ReplayCommand};
10
11/// Inclusive command-id bounds for the replayable hot journal.
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub struct JournalCommandIdBounds {
14 pub min_command_id: i64,
15 pub max_command_id: i64,
16}
17
18/// Read-only queries for engine journal replay after snapshot recovery.
19pub trait JournalReplayReader: Send + Sync {
20 /// Next command_id for sequence initialization (MAX + 1, or 1 if empty).
21 fn get_next_engine_command_id_sync(&self) -> Result<i64>;
22
23 /// Inclusive command-id bounds for replayable rows in `engine_commands`.
24 fn get_journal_command_id_bounds_sync(&self) -> Result<Option<JournalCommandIdBounds>>;
25
26 /// Count durable non-replayable journal rows in a command-id range
27 /// (exclusive start, inclusive end).
28 fn count_non_replayable_commands_in_range_sync(
29 &self,
30 start_command_id: i64,
31 end_command_id: i64,
32 ) -> Result<i64>;
33
34 /// Fetch commands that produced L2 events after the snapshot's L2 sequence.
35 /// Used for the primary replay path (Pass 1).
36 fn get_commands_with_l2_after_seq_sync(&self, l2_seq: i64) -> Result<Vec<ReplayCommand>>;
37
38 /// Paginated replay cursor: fetch up to `limit` commands after `after_command_id`,
39 /// optionally bounded by `up_to_command_id`.
40 fn get_replay_commands_after_command_id_sync(
41 &self,
42 after_command_id: i64,
43 up_to_command_id: Option<i64>,
44 limit: i64,
45 ) -> Result<Vec<ReplayCommand>>;
46
47 /// Raw OrderFilled event payloads in a command_id range (exclusive start, inclusive end).
48 fn get_fill_events_for_command_range_sync(
49 &self,
50 start_command_id: i64,
51 end_command_id: i64,
52 ) -> Result<Vec<Vec<u8>>>;
53
54 /// Portfolio-relevant events (OrderFilled + PositionExpired) in a command_id range.
55 /// Used during portfolio cache replay.
56 fn get_portfolio_events_for_command_range_sync(
57 &self,
58 start_command_id: i64,
59 end_command_id: i64,
60 ) -> Result<Vec<PortfolioReplayEvent>>;
61
62 /// Raw OrderUpdate event payloads in a command_id range (exclusive start, inclusive end).
63 fn get_order_update_events_for_command_range_sync(
64 &self,
65 start_command_id: i64,
66 end_command_id: i64,
67 ) -> Result<Vec<Vec<u8>>>;
68
69 /// Maximum L2 sequence from engine_events. Returns 0 if no L2 events exist.
70 fn get_max_l2_seq_from_events_sync(&self) -> Result<i64>;
71
72 /// Raw OrderFilled event payloads after the snapshot boundary (by L2 sequence).
73 /// Used during replay Pass 2 (fill reconciliation).
74 fn get_fill_events_after_seq_sync(&self, l2_seq: i64) -> Result<Vec<Vec<u8>>>;
75
76 /// Raw OrderUpdate event payloads after the snapshot boundary (by L2 sequence).
77 /// Used during replay Pass 3 (side-effect cancel detection).
78 fn get_order_update_events_after_seq_sync(&self, l2_seq: i64) -> Result<Vec<Vec<u8>>>;
79}