1use orbok_core::{FileId, JobId, JobType, SourceId};
9use serde::{Deserialize, Serialize};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
19#[serde(rename_all = "snake_case")]
20pub enum WorkPriority {
21 Maintenance = 0,
22 LowBackground = 1,
23 NormalBackground = 2,
24 UserVisible = 3,
25 UserBlocking = 4,
26}
27
28impl Default for WorkPriority {
29 fn default() -> Self {
30 WorkPriority::NormalBackground
31 }
32}
33
34impl WorkPriority {
35 pub fn as_i64(self) -> i64 {
41 self as i64
42 }
43
44 pub fn from_i64(v: i64) -> Self {
45 match v {
46 4 => Self::UserBlocking,
47 3 => Self::UserVisible,
48 2 => Self::NormalBackground,
49 1 => Self::LowBackground,
50 _ => Self::Maintenance,
51 }
52 }
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
63#[serde(rename_all = "snake_case")]
64pub enum JobState {
65 Pending,
66 Running,
67 Paused,
68 Completed,
69 Failed,
70 Cancelled,
71 WaitingForDependency,
72}
73
74#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
82#[serde(rename_all = "snake_case")]
83pub enum JobKind {
84 ScanSource,
85 ExtractFile,
86 ChunkFile,
87 UpdateKeywordIndex,
88 GenerateEmbedding,
89 Cleanup,
90 Repair,
91}
92
93impl JobKind {
94 pub fn as_job_type(self) -> JobType {
96 match self {
97 JobKind::ScanSource => JobType::Scan,
98 JobKind::ExtractFile => JobType::Extract,
99 JobKind::ChunkFile => JobType::Chunk,
100 JobKind::UpdateKeywordIndex => JobType::KeywordIndex,
101 JobKind::GenerateEmbedding => JobType::Embedding,
102 JobKind::Cleanup => JobType::DeleteStale,
103 JobKind::Repair => JobType::Rebuild,
104 }
105 }
106
107 pub fn default_priority(self) -> WorkPriority {
109 match self {
110 JobKind::ScanSource => WorkPriority::NormalBackground,
111 JobKind::ExtractFile => WorkPriority::NormalBackground,
112 JobKind::ChunkFile => WorkPriority::NormalBackground,
113 JobKind::UpdateKeywordIndex => WorkPriority::NormalBackground,
114 JobKind::GenerateEmbedding => WorkPriority::LowBackground,
115 JobKind::Cleanup => WorkPriority::Maintenance,
116 JobKind::Repair => WorkPriority::Maintenance,
117 }
118 }
119}
120
121#[derive(Debug, Clone)]
125pub struct IndexJob {
126 pub id: JobId,
127 pub file_id: Option<FileId>,
128 pub source_id: SourceId,
129 pub kind: JobKind,
130 pub priority: WorkPriority,
131 pub state: JobState,
132 pub attempt_count: u32,
133 pub last_error_kind: Option<String>,
134}
135
136impl IndexJob {
137 pub fn new(source_id: SourceId, kind: JobKind) -> Self {
138 Self {
139 id: JobId::generate(),
140 file_id: None,
141 source_id,
142 priority: kind.default_priority(),
143 kind,
144 state: JobState::Pending,
145 attempt_count: 0,
146 last_error_kind: None,
147 }
148 }
149
150 pub fn with_file(mut self, file_id: FileId) -> Self {
151 self.file_id = Some(file_id);
152 self
153 }
154
155 pub fn with_priority(mut self, priority: WorkPriority) -> Self {
156 self.priority = priority;
157 self
158 }
159}
160
161#[derive(Debug, Clone)]
169pub enum SchedulerEvent {
170 JobQueued(JobId),
171 JobStarted(JobId),
172 JobPaused(JobId),
173 JobResumed(JobId),
174 JobCompleted(JobId),
175 JobFailed {
176 id: JobId,
177 error_kind: String,
178 },
179 JobCancelled(JobId),
180 QueueBackpressureApplied(QueueKind),
181 QueueBackpressureReleased(QueueKind),
182 UserActivityDetected,
183 ResourceModeChanged(ResourceMode),
184 PartialReadinessChanged {
185 ready_count: u64,
186 pending_count: u64,
187 },
188}
189
190#[derive(Debug, Clone, Copy, PartialEq, Eq)]
192pub enum QueueKind {
193 Scan,
194 Extract,
195 Chunk,
196 Keyword,
197 Embedding,
198 Maintenance,
199}
200
201#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
205pub enum ResourceMode {
206 #[default]
208 Normal,
209 UserActive,
211 LowImpact,
213 Paused,
215}