netmito/entity/
state.rs

1use std::{convert::Infallible, fmt::Display, str::FromStr};
2
3use clap::ValueEnum;
4use matrix_match::matrix_match;
5use redis::FromRedisValue;
6use sea_orm::entity::prelude::*;
7use serde::{Deserialize, Serialize};
8
9use crate::schema::{TaskResultMessage, TaskResultSpec};
10
11#[derive(EnumIter, DeriveActiveEnum, Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
12#[sea_orm(rs_type = "i32", db_type = "Integer")]
13pub enum UserState {
14    Active = 0,
15    Locked = 1,
16    Deleted = 2,
17}
18
19impl Display for UserState {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        match self {
22            UserState::Active => write!(f, "Active"),
23            UserState::Locked => write!(f, "Locked"),
24            UserState::Deleted => write!(f, "Deleted"),
25        }
26    }
27}
28
29#[derive(EnumIter, DeriveActiveEnum, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
30#[sea_orm(rs_type = "i32", db_type = "Integer")]
31pub enum GroupState {
32    Active = 0,
33    Locked = 1,
34    Deleted = 2,
35}
36
37impl Display for GroupState {
38    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39        match self {
40            GroupState::Active => write!(f, "Active"),
41            GroupState::Locked => write!(f, "Locked"),
42            GroupState::Deleted => write!(f, "Deleted"),
43        }
44    }
45}
46
47#[derive(
48    EnumIter,
49    DeriveActiveEnum,
50    Clone,
51    Debug,
52    PartialEq,
53    Eq,
54    Serialize,
55    Deserialize,
56    Copy,
57    ValueEnum,
58    Hash,
59)]
60#[sea_orm(rs_type = "i32", db_type = "Integer")]
61pub enum TaskState {
62    /// Reserved for future use
63    Pending = 0,
64    /// Task is ready to be fetched and executed
65    Ready = 1,
66    /// Task is being executed by some worker
67    Running = 2,
68    /// Task has been successfully executed, but not sure if it succeeded or not
69    Finished = 3,
70    /// Task is canceled by the worker due to timeout
71    Cancelled = 4,
72    Unknown = 5,
73}
74
75impl Display for TaskState {
76    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77        match self {
78            TaskState::Pending => write!(f, "Pending"),
79            TaskState::Ready => write!(f, "Ready"),
80            TaskState::Running => write!(f, "Running"),
81            TaskState::Finished => write!(f, "Finished"),
82            TaskState::Cancelled => write!(f, "Cancelled"),
83            TaskState::Unknown => write!(f, "Unknown"),
84        }
85    }
86}
87
88impl TaskState {
89    pub fn is_reach(&self, target_state: &TaskExecState, result: Option<TaskResultSpec>) -> bool {
90        match self {
91            TaskState::Pending | TaskState::Ready | TaskState::Unknown => false,
92            TaskState::Running => matches!(target_state, TaskExecState::FetchResource),
93            TaskState::Finished => match target_state {
94                TaskExecState::WorkerExited => false,
95                TaskExecState::FetchResource => true,
96                TaskExecState::FetchResourceFinished => true,
97                TaskExecState::FetchResourceError => false,
98                TaskExecState::FetchResourceTimeout => false,
99                TaskExecState::FetchResourceNotFound => false,
100                TaskExecState::FetchResourceForbidden => false,
101                TaskExecState::Watch => true,
102                TaskExecState::WatchFinished => true,
103                TaskExecState::WatchTimeout => false,
104                TaskExecState::ExecPending => true,
105                TaskExecState::ExecSpawned => true,
106                TaskExecState::ExecFinished => true,
107                TaskExecState::ExecTimeout => false,
108                TaskExecState::UploadResult => true,
109                TaskExecState::UploadFinishedResult => true,
110                TaskExecState::UploadCancelledResult => false,
111                TaskExecState::UploadResultFinished => result.is_some(),
112                TaskExecState::UploadResultTimeout => false,
113                TaskExecState::TaskCommitted => result.is_some(),
114                TaskExecState::Unknown => false,
115            },
116            TaskState::Cancelled => match result {
117                Some(result_spec) => match result_spec.msg {
118                    Some(msg) => matrix_match!(
119                        (target_state, msg); TaskResultMessage::FetchResourceTimeout, TaskResultMessage::ExecTimeout, TaskResultMessage::UploadResultTimeout, TaskResultMessage::ResourceNotFound, TaskResultMessage::ResourceForbidden, TaskResultMessage::WatchTimeout, TaskResultMessage::UserCancellation, TaskResultMessage::SubmitNewTaskFailed =>
120                        TaskExecState::WorkerExited             => false, false, false, false, false, false, false, false;
121                        TaskExecState::FetchResource            => false, false, false, false, false, false, false, true;
122                        TaskExecState::FetchResourceFinished    => false, false, false, false, false, false, false, true;
123                        TaskExecState::FetchResourceError       => false, false, false, false, false, false, false, false;
124                        TaskExecState::FetchResourceTimeout     => true,  false, false, false, false, false, false, false;
125                        TaskExecState::FetchResourceNotFound    => false, false, false, true,  false, false, false, false;
126                        TaskExecState::FetchResourceForbidden   => false, false, false, false, true,  false, false, false;
127                        TaskExecState::Watch                    => false, false, false, false, false, false, false, true;
128                        TaskExecState::WatchFinished            => false, false, false, false, false, false, false, true;
129                        TaskExecState::WatchTimeout             => false, false, false, false, false, true,  false, false;
130                        TaskExecState::ExecPending              => false, false, false, false, false, false, false, true;
131                        TaskExecState::ExecSpawned              => false, false, false, false, false, false, false, true;
132                        TaskExecState::ExecFinished             => false, false, false, false, false, false, false, true;
133                        TaskExecState::ExecTimeout              => false, true,  false, false, false, false, false, false;
134                        TaskExecState::UploadResult             => true,  true,  true,  true,  true,  true,  false, true;
135                        TaskExecState::UploadFinishedResult     => false, false, false, false, false, false, false, false;
136                        TaskExecState::UploadCancelledResult    => true,  true,  true,  true,  true,  true,  false, false;
137                        TaskExecState::UploadResultFinished     => true,  true,  true,  true,  true,  true,  false, true;
138                        TaskExecState::UploadResultTimeout      => false, false, true,  false, false, false, false, false;
139                        TaskExecState::TaskCommitted            => true,  true,  true,  true,  true,  true,  true,  true;
140                        TaskExecState::Unknown                  => false, false, false, false, false, false, false, false;
141                    ),
142                    None => false,
143                },
144                None => false,
145            },
146        }
147    }
148}
149
150// This is specific to the task execution state (the lifetime of its execution in a worker)
151#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Copy)]
152pub enum TaskExecState {
153    WorkerExited = -1,
154    FetchResource = 1,
155    FetchResourceFinished = 2,
156    FetchResourceError = 3,
157    FetchResourceTimeout = 4,
158    FetchResourceNotFound = 5,
159    FetchResourceForbidden = 6,
160    Watch = 7,
161    WatchFinished = 8,
162    WatchTimeout = 9,
163    ExecPending = 10,
164    ExecSpawned = 11,
165    ExecFinished = 12,
166    ExecTimeout = 13,
167    UploadResult = 14,
168    UploadFinishedResult = 15,
169    UploadCancelledResult = 16,
170    UploadResultFinished = 17,
171    UploadResultTimeout = 18,
172    TaskCommitted = 19,
173    Unknown = -99,
174}
175
176impl From<i32> for TaskExecState {
177    fn from(v: i32) -> Self {
178        match v {
179            -1 => TaskExecState::WorkerExited,
180            1 => TaskExecState::FetchResource,
181            2 => TaskExecState::FetchResourceFinished,
182            3 => TaskExecState::FetchResourceError,
183            4 => TaskExecState::FetchResourceTimeout,
184            5 => TaskExecState::FetchResourceNotFound,
185            6 => TaskExecState::FetchResourceForbidden,
186            7 => TaskExecState::Watch,
187            8 => TaskExecState::WatchFinished,
188            9 => TaskExecState::WatchTimeout,
189            10 => TaskExecState::ExecPending,
190            11 => TaskExecState::ExecSpawned,
191            12 => TaskExecState::ExecFinished,
192            13 => TaskExecState::ExecTimeout,
193            14 => TaskExecState::UploadResult,
194            15 => TaskExecState::UploadFinishedResult,
195            16 => TaskExecState::UploadCancelledResult,
196            17 => TaskExecState::UploadResultFinished,
197            18 => TaskExecState::UploadResultTimeout,
198            19 => TaskExecState::TaskCommitted,
199            _ => TaskExecState::Unknown,
200        }
201    }
202}
203
204impl FromStr for TaskExecState {
205    type Err = Infallible;
206
207    fn from_str(s: &str) -> Result<Self, Self::Err> {
208        match s {
209            "WorkerExited" => Ok(TaskExecState::WorkerExited),
210            "FetchResource" => Ok(TaskExecState::FetchResource),
211            "FetchResourceFinished" => Ok(TaskExecState::FetchResourceFinished),
212            "FetchResourceError" => Ok(TaskExecState::FetchResourceError),
213            "FetchResourceTimeout" => Ok(TaskExecState::FetchResourceTimeout),
214            "FetchResourceNotFound" => Ok(TaskExecState::FetchResourceNotFound),
215            "FetchResourceForbidden" => Ok(TaskExecState::FetchResourceForbidden),
216            "Watch" => Ok(TaskExecState::Watch),
217            "WatchFinished" => Ok(TaskExecState::WatchFinished),
218            "WatchTimeout" => Ok(TaskExecState::WatchTimeout),
219            "ExecPending" => Ok(TaskExecState::ExecPending),
220            "ExecSpawned" => Ok(TaskExecState::ExecSpawned),
221            "ExecFinished" => Ok(TaskExecState::ExecFinished),
222            "ExecTimeout" => Ok(TaskExecState::ExecTimeout),
223            "UploadResult" => Ok(TaskExecState::UploadResult),
224            "UploadFinishedResult" => Ok(TaskExecState::UploadFinishedResult),
225            "UploadCancelledResult" => Ok(TaskExecState::UploadCancelledResult),
226            "UploadResultFinished" => Ok(TaskExecState::UploadResultFinished),
227            "UploadResultTimeout" => Ok(TaskExecState::UploadResultTimeout),
228            "TaskCommitted" => Ok(TaskExecState::TaskCommitted),
229            _ => Ok(TaskExecState::Unknown),
230        }
231    }
232}
233
234impl TaskExecState {
235    pub fn is_reach(&self, target_state: &TaskExecState) -> bool {
236        matrix_match!(
237            (target_state, self) ; TaskExecState::WorkerExited, TaskExecState::FetchResource, TaskExecState::FetchResourceFinished, TaskExecState::FetchResourceError, TaskExecState::FetchResourceTimeout, TaskExecState::FetchResourceNotFound, TaskExecState::FetchResourceForbidden, TaskExecState::Watch, TaskExecState::WatchFinished, TaskExecState::WatchTimeout, TaskExecState::ExecPending, TaskExecState::ExecSpawned, TaskExecState::ExecFinished, TaskExecState::ExecTimeout, TaskExecState::UploadResult, TaskExecState::UploadFinishedResult, TaskExecState::UploadCancelledResult, TaskExecState::UploadResultFinished, TaskExecState::UploadResultTimeout, TaskExecState::TaskCommitted, TaskExecState::Unknown =>
238            TaskExecState::WorkerExited             => false,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false, false,   false,  false,  false,  false,  false,  false,  false,  false;
239            TaskExecState::FetchResource            => false,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   false;
240            TaskExecState::FetchResourceFinished    => false,   false,  true,   false,  false,  false,  false,  true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   false;
241            TaskExecState::FetchResourceError       => false,   false,  false,  true,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false;
242            TaskExecState::FetchResourceTimeout     => false,   false,  false,  false,  true,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false;
243            TaskExecState::FetchResourceNotFound    => false,   false,  false,  false,  false,  true,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false;
244            TaskExecState::FetchResourceForbidden   => false,   false,  false,  false,  false,  false,  true,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false;
245            TaskExecState::Watch                    => false,   false,  false,  false,  false,  false,  false,  true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   false;
246            TaskExecState::WatchFinished            => false,   false,  false,  false,  false,  false,  false,  false,  true,   false,  true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   false;
247            TaskExecState::WatchTimeout             => false,   false,  false,  false,  false,  false,  false,  false,  false,  true,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false;
248            TaskExecState::ExecPending              => false,   false,  false,  false,  false,  false,  false,  false,  false,  false,  true,   true,   true,   true,   true,   true,   true,   true,   true,   true,   false;
249            TaskExecState::ExecSpawned              => false,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  true,   true,   true,   true,   true,   true,   true,   true,   true,   false;
250            TaskExecState::ExecFinished             => false,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  true,   false,  false,  true,   false,  false,  false,  false,  false;
251            TaskExecState::ExecTimeout              => false,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  true,   false,  false,  true,   false,  false,  false,  false;
252            TaskExecState::UploadResult             => false,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  true,   true,   true,   true,   true,   true,   false;
253            TaskExecState::UploadFinishedResult     => false,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  true,   false,  false,  false,  false,  false;
254            TaskExecState::UploadCancelledResult    => false,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  true,   false,  false,  false,  false;
255            TaskExecState::UploadResultFinished     => false,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  true,   false,  false,  false;
256            TaskExecState::UploadResultTimeout      => false,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  true,   false,  false;
257            TaskExecState::TaskCommitted            => false,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  true,   false;
258            TaskExecState::Unknown                  => false,   false,  false,  false,  false,  false,  false,  false,  false,  false,  false,  false, false,   false,  false,  false,  false,  false,  false,  false,  false;
259        )
260    }
261
262    pub fn is_end(&self) -> bool {
263        matches!(
264            self,
265            TaskExecState::FetchResourceError | TaskExecState::TaskCommitted
266        )
267    }
268}
269
270impl FromRedisValue for TaskExecState {
271    fn from_redis_value(v: &redis::Value) -> redis::RedisResult<Self> {
272        let i = i32::from_redis_value(v)?;
273        Ok(i.into())
274    }
275
276    fn from_owned_redis_value(v: redis::Value) -> redis::RedisResult<Self> {
277        let i = i32::from_owned_redis_value(v)?;
278        Ok(i.into())
279    }
280}
281
282#[derive(EnumIter, DeriveActiveEnum, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Copy)]
283#[sea_orm(rs_type = "i32", db_type = "Integer")]
284pub enum WorkerState {
285    Normal = 0,
286    /// Worker is being shutdown gracefully. It should only be shutdown when fetching new task
287    GracefulShutdown = 1,
288}
289
290impl Display for WorkerState {
291    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
292        match self {
293            WorkerState::Normal => write!(f, "Normal"),
294            WorkerState::GracefulShutdown => write!(f, "GracefulShutdown"),
295        }
296    }
297}