systemprompt_models/services/
scheduler.rs1use std::collections::HashMap;
7
8use serde::{Deserialize, Serialize};
9use systemprompt_identifiers::UserId;
10pub use systemprompt_provider_contracts::JobScope;
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
13#[serde(deny_unknown_fields)]
14pub struct JobConfig {
15 #[serde(default)]
16 pub extension: Option<String>,
17 pub name: String,
18 #[serde(default)]
19 pub owner: Option<UserId>,
20 #[serde(default = "default_true")]
21 pub enabled: bool,
22 #[serde(default)]
23 pub schedule: Option<String>,
24 #[serde(default)]
25 pub enforce: bool,
26 #[serde(default)]
27 pub parameters: HashMap<String, String>,
28 #[serde(default)]
29 pub scope: Option<JobScope>,
30}
31
32const fn default_true() -> bool {
33 true
34}
35
36impl JobConfig {
37 #[must_use]
38 pub fn new(name: impl Into<String>) -> Self {
39 Self {
40 extension: None,
41 name: name.into(),
42 owner: None,
43 enabled: true,
44 schedule: None,
45 enforce: false,
46 parameters: HashMap::new(),
47 scope: None,
48 }
49 }
50
51 #[must_use]
52 pub const fn with_enforce(mut self) -> Self {
53 self.enforce = true;
54 self
55 }
56
57 #[must_use]
58 pub fn with_owner(mut self, owner: UserId) -> Self {
59 self.owner = Some(owner);
60 self
61 }
62
63 #[must_use]
64 pub fn with_extension(mut self, extension: impl Into<String>) -> Self {
65 self.extension = Some(extension.into());
66 self
67 }
68
69 #[must_use]
70 pub fn with_schedule(mut self, schedule: impl Into<String>) -> Self {
71 self.schedule = Some(schedule.into());
72 self
73 }
74
75 #[must_use]
76 pub fn with_parameters(mut self, parameters: HashMap<String, String>) -> Self {
77 self.parameters = parameters;
78 self
79 }
80
81 #[must_use]
82 pub const fn with_scope(mut self, scope: JobScope) -> Self {
83 self.scope = Some(scope);
84 self
85 }
86
87 #[must_use]
88 pub const fn disabled(mut self) -> Self {
89 self.enabled = false;
90 self
91 }
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize)]
95pub struct SchedulerConfig {
96 #[serde(default = "default_true")]
97 pub enabled: bool,
98 #[serde(default)]
99 pub jobs: Vec<JobConfig>,
100 #[serde(default = "default_bootstrap_jobs")]
101 pub bootstrap_jobs: Vec<String>,
102 #[serde(default = "default_true")]
103 pub distributed_lock: bool,
104}
105
106fn default_bootstrap_jobs() -> Vec<String> {
107 vec!["cleanup_inactive_sessions".to_owned()]
108}
109
110impl SchedulerConfig {
111 #[must_use]
112 pub fn with_system_admin() -> Self {
113 Self {
114 enabled: true,
115 jobs: vec![
116 JobConfig::new("cleanup_anonymous_users")
117 .with_extension("core")
118 .with_schedule("0 0 3 * * *")
119 .with_enforce(),
120 JobConfig::new("cleanup_empty_contexts")
121 .with_extension("core")
122 .with_schedule("0 0 * * * *")
123 .with_enforce(),
124 JobConfig::new("cleanup_inactive_sessions")
125 .with_extension("core")
126 .with_schedule("0 0 * * * *"),
127 JobConfig::new("database_cleanup")
128 .with_extension("core")
129 .with_schedule("0 0 4 * * *")
130 .with_enforce(),
131 ],
132 bootstrap_jobs: default_bootstrap_jobs(),
133 distributed_lock: true,
134 }
135 }
136}