1use std::time::Instant;
4
5use crate::config::WorkersConfig;
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum SlotState {
10 Spawning,
12 Idle,
14 Busy,
16 Stopping,
18 Dead,
20}
21
22pub struct SlotInfo {
24 pub state: SlotState,
25 pub pid: Option<u32>,
26 pub jobs_handled: u64,
27 pub created_at: Instant,
28}
29
30impl SlotInfo {
31 pub fn new() -> Self {
32 Self {
33 state: SlotState::Spawning,
34 pid: None,
35 jobs_handled: 0,
36 created_at: Instant::now(),
37 }
38 }
39
40 pub fn should_recycle(&self, cfg: &WorkersConfig) -> bool {
42 if self.jobs_handled >= cfg.max_jobs {
43 return true;
44 }
45 if self.created_at.elapsed() >= cfg.ttl {
46 return true;
47 }
48 false
49 }
50
51 pub fn mark_ready(&mut self, pid: u32) {
53 debug_assert!(matches!(self.state, SlotState::Spawning));
54 self.state = SlotState::Idle;
55 self.pid = Some(pid);
56 }
57
58 pub fn mark_busy(&mut self) {
60 debug_assert!(matches!(self.state, SlotState::Idle));
61 self.state = SlotState::Busy;
62 }
63
64 pub fn mark_idle(&mut self) {
66 debug_assert!(matches!(self.state, SlotState::Busy | SlotState::Stopping));
67 self.jobs_handled += 1;
68 if matches!(self.state, SlotState::Busy) {
69 self.state = SlotState::Idle;
70 }
71 }
73
74 pub fn mark_dead(&mut self) {
76 self.state = SlotState::Dead;
77 }
78
79 pub fn request_stop(&mut self) {
81 if matches!(self.state, SlotState::Idle | SlotState::Busy) {
82 self.state = SlotState::Stopping;
83 }
84 }
85}
86
87impl Default for SlotInfo {
88 fn default() -> Self {
89 Self::new()
90 }
91}