openraft/engine/handler/snapshot_handler/
mod.rs

1//! This mod handles state machine operations
2
3use crate::core::sm;
4use crate::engine::Command;
5use crate::engine::EngineOutput;
6use crate::raft_state::LogStateReader;
7use crate::summary::MessageSummary;
8use crate::AsyncRuntime;
9use crate::RaftState;
10use crate::RaftTypeConfig;
11use crate::SnapshotMeta;
12
13#[cfg(test)]
14mod trigger_snapshot_test;
15#[cfg(test)]
16mod update_snapshot_test;
17
18/// Handle raft vote related operations
19pub(crate) struct SnapshotHandler<'st, 'out, C>
20where C: RaftTypeConfig
21{
22    pub(crate) state: &'st mut RaftState<C::NodeId, C::Node, <C::AsyncRuntime as AsyncRuntime>::Instant>,
23    pub(crate) output: &'out mut EngineOutput<C>,
24}
25
26impl<C> SnapshotHandler<'_, '_, C>
27where C: RaftTypeConfig
28{
29    /// Trigger building snapshot if there is no pending building job.
30    #[tracing::instrument(level = "debug", skip_all)]
31    pub(crate) fn trigger_snapshot(&mut self) -> bool {
32        tracing::debug!("{}", func_name!());
33
34        if self.state.io_state_mut().building_snapshot() {
35            tracing::debug!("snapshot building is in progress, do not trigger snapshot");
36            return false;
37        }
38
39        tracing::info!("push snapshot building command");
40
41        self.state.io_state.set_building_snapshot(true);
42
43        self.output.push_command(Command::from(sm::Command::build_snapshot()));
44        true
45    }
46
47    /// Update engine state when a new snapshot is built or installed.
48    ///
49    /// Engine records only the metadata of a snapshot. Snapshot data is stored by RaftStorage
50    /// implementation.
51    #[tracing::instrument(level = "debug", skip_all)]
52    pub(crate) fn update_snapshot(&mut self, meta: SnapshotMeta<C::NodeId, C::Node>) -> bool {
53        tracing::info!("update_snapshot: {:?}", meta);
54
55        if meta.last_log_id <= self.state.snapshot_last_log_id().cloned() {
56            tracing::info!(
57                "No need to install a smaller snapshot: current snapshot last_log_id({}), new snapshot last_log_id({})",
58                self.state.snapshot_last_log_id().summary(),
59                meta.last_log_id.summary()
60            );
61            return false;
62        }
63
64        self.state.snapshot_meta = meta;
65
66        true
67    }
68}