wasmer_journal/
snapshot.rs

1use super::*;
2
3/// Various triggers that will cause the runtime to take snapshot
4/// of the WASM state and store it in the snapshot file.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
6pub enum SnapshotTrigger {
7    /// Triggered when all the threads in the process goes idle
8    Idle,
9    /// Triggered when a listen syscall is invoked on a socket for the first time
10    FirstListen,
11    /// Triggered on reading the environment variables for the first time
12    FirstEnviron,
13    /// Triggered when the process reads stdin for the first time
14    FirstStdin,
15    /// Issued on the first interrupt signal (Ctrl + C) the process receives, after that normal CTRL-C will apply.
16    FirstSigint,
17    /// Triggered periodically based on a interval (default 10 seconds) which can be specified using the `snapshot-interval` option
18    PeriodicInterval,
19    /// Issued if the user sends an interrupt signal (Ctrl + C).
20    Sigint,
21    /// Alarm clock signal (used for timers)
22    Sigalrm,
23    /// The SIGTSTP signal is sent to a process by its controlling terminal to request it to stop temporarily. It is commonly initiated by the user pressing Ctrl-Z.
24    Sigtstp,
25    /// The SIGSTOP signal instructs the operating system to stop a process for later resumption.
26    Sigstop,
27    /// When a non-determinstic call is made
28    NonDeterministicCall,
29    /// Bootstrapping process
30    Bootstrap,
31    /// Transaction
32    Transaction,
33    /// Explicitly requested by the guest module
34    Explicit,
35}
36
37impl SnapshotTrigger {
38    pub fn only_once(&self) -> bool {
39        matches!(
40            self,
41            Self::FirstListen
42                | Self::FirstEnviron
43                | Self::FirstStdin
44                | Self::FirstSigint
45                // TODO: I don't think this should be an only_once trigger, but
46                // repeatable triggers currently get stuck in a loop
47                | Self::Explicit
48        )
49    }
50}
51
52pub const DEFAULT_SNAPSHOT_TRIGGERS: [SnapshotTrigger; 5] = [
53    SnapshotTrigger::Idle,
54    SnapshotTrigger::FirstEnviron,
55    SnapshotTrigger::FirstListen,
56    SnapshotTrigger::FirstStdin,
57    SnapshotTrigger::Explicit,
58];
59
60impl FromStr for SnapshotTrigger {
61    type Err = anyhow::Error;
62
63    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
64        let s = s.trim().to_lowercase();
65        Ok(match s.as_str() {
66            "idle" => Self::Idle,
67            "first-listen" => Self::FirstListen,
68            "first-stdin" => Self::FirstStdin,
69            "first-environ" => Self::FirstEnviron,
70            "first-intr" | "first-sigint" | "first-ctrlc" | "first-ctrl-c" => Self::FirstSigint,
71            "periodic-interval" => Self::PeriodicInterval,
72            "intr" | "sigint" | "ctrlc" | "ctrl-c" => Self::Sigint,
73            "alarm" | "timer" | "sigalrm" => Self::Sigalrm,
74            "sigtstp" | "ctrlz" | "ctrl-z" => Self::Sigtstp,
75            "stop" | "sigstop" => Self::Sigstop,
76            "non-deterministic-call" => Self::NonDeterministicCall,
77            "bootstrap" => Self::Bootstrap,
78            "transaction" => Self::Transaction,
79            "explicit" => Self::Explicit,
80            a => return Err(anyhow::format_err!("invalid or unknown trigger ({a})")),
81        })
82    }
83}