wasmer_config/app/
snapshot_trigger.rs

1use std::{fmt::Display, str::FromStr};
2
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize, de::Error};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub enum SnapshotTrigger {
8    /// Triggered when all the threads in the process goes idle
9    Idle,
10    /// Triggered when a listen syscall is invoked on a socket for the first time
11    FirstListen,
12    /// Triggered on reading the environment variables for the first time
13    FirstEnviron,
14    /// Triggered when the process reads stdin for the first time
15    FirstStdin,
16    /// Issued on the first interrupt signal (Ctrl + C) the process receives, after that normal CTRL-C will apply.
17    FirstSigint,
18    /// Triggered periodically based on a interval (default 10 seconds) which can be specified using the `snapshot-interval` option
19    PeriodicInterval,
20    /// Issued if the user sends an interrupt signal (Ctrl + C).
21    Sigint,
22    /// Alarm clock signal (used for timers)
23    Sigalrm,
24    /// 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.
25    Sigtstp,
26    /// The SIGSTOP signal instructs the operating system to stop a process for later resumption.
27    Sigstop,
28    /// When a non-determinstic call is made
29    NonDeterministicCall,
30    /// Bootstrapping process
31    Bootstrap,
32    /// Transaction
33    Transaction,
34    /// Explicitly requested by the guest module
35    Explicit,
36}
37
38impl SnapshotTrigger {
39    pub fn to_str(&self) -> &'static str {
40        match self {
41            Self::Bootstrap => "bootstrap",
42            Self::Explicit => "explicit",
43            Self::FirstEnviron => "first-environ",
44            Self::FirstListen => "first-listen",
45            Self::FirstSigint => "first-sigint",
46            Self::FirstStdin => "first-stdin",
47            Self::Idle => "idle",
48            Self::NonDeterministicCall => "non-deterministic-call",
49            Self::PeriodicInterval => "periodic-interval",
50            Self::Sigalrm => "sigalrm",
51            Self::Sigint => "sigint",
52            Self::Sigtstp => "sigtstp",
53            Self::Sigstop => "sigstop",
54            Self::Transaction => "transaction",
55        }
56    }
57}
58
59impl FromStr for SnapshotTrigger {
60    type Err = anyhow::Error;
61
62    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
63        let s = s.trim().to_lowercase();
64        Ok(match s.as_str() {
65            "idle" => Self::Idle,
66            "first-listen" => Self::FirstListen,
67            "first-stdin" => Self::FirstStdin,
68            "first-environ" => Self::FirstEnviron,
69            "first-intr" | "first-sigint" | "first-ctrlc" | "first-ctrl-c" => Self::FirstSigint,
70            "periodic-interval" => Self::PeriodicInterval,
71            "intr" | "sigint" | "ctrlc" | "ctrl-c" => Self::Sigint,
72            "alarm" | "timer" | "sigalrm" => Self::Sigalrm,
73            "sigtstp" | "ctrlz" | "ctrl-z" => Self::Sigtstp,
74            "stop" | "sigstop" => Self::Sigstop,
75            "non-deterministic-call" => Self::NonDeterministicCall,
76            "bootstrap" => Self::Bootstrap,
77            "transaction" => Self::Transaction,
78            "explicit" => Self::Explicit,
79            a => return Err(anyhow::format_err!("invalid or unknown trigger ({a})")),
80        })
81    }
82}
83
84impl Display for SnapshotTrigger {
85    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86        write!(f, "{}", self.to_str())
87    }
88}
89
90impl Serialize for SnapshotTrigger {
91    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
92    where
93        S: serde::Serializer,
94    {
95        serializer.serialize_str(self.to_str())
96    }
97}
98
99impl<'de> Deserialize<'de> for SnapshotTrigger {
100    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
101    where
102        D: serde::Deserializer<'de>,
103    {
104        <&str as Deserialize>::deserialize(deserializer)
105            .and_then(|s| s.parse::<SnapshotTrigger>().map_err(D::Error::custom))
106    }
107}
108
109impl JsonSchema for SnapshotTrigger {
110    fn schema_name() -> String {
111        "SnapshotTrigger".to_owned()
112    }
113
114    fn json_schema(generator: &mut schemars::r#gen::SchemaGenerator) -> schemars::schema::Schema {
115        <String as JsonSchema>::json_schema(generator)
116    }
117}