Skip to main content

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}