systemprompt_provider_contracts/
job.rs1use anyhow::Result;
2use async_trait::async_trait;
3use std::sync::Arc;
4
5#[derive(Debug, Clone)]
6pub struct JobResult {
7 pub success: bool,
8 pub message: Option<String>,
9 pub items_processed: Option<u64>,
10 pub items_failed: Option<u64>,
11 pub duration_ms: u64,
12}
13
14impl JobResult {
15 pub const fn success() -> Self {
16 Self {
17 success: true,
18 message: None,
19 items_processed: None,
20 items_failed: None,
21 duration_ms: 0,
22 }
23 }
24
25 pub fn with_message(mut self, message: impl Into<String>) -> Self {
26 self.message = Some(message.into());
27 self
28 }
29
30 pub const fn with_stats(mut self, processed: u64, failed: u64) -> Self {
31 self.items_processed = Some(processed);
32 self.items_failed = Some(failed);
33 self
34 }
35
36 pub const fn with_duration(mut self, duration_ms: u64) -> Self {
37 self.duration_ms = duration_ms;
38 self
39 }
40
41 pub fn failure(message: impl Into<String>) -> Self {
42 Self {
43 success: false,
44 message: Some(message.into()),
45 items_processed: None,
46 items_failed: None,
47 duration_ms: 0,
48 }
49 }
50}
51
52pub struct JobContext {
53 db_pool: Arc<dyn std::any::Any + Send + Sync>,
54 app_context: Arc<dyn std::any::Any + Send + Sync>,
55}
56
57impl std::fmt::Debug for JobContext {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 f.debug_struct("JobContext")
60 .field("db_pool", &"<type-erased>")
61 .field("app_context", &"<type-erased>")
62 .finish()
63 }
64}
65
66impl JobContext {
67 pub fn new(
68 db_pool: Arc<dyn std::any::Any + Send + Sync>,
69 app_context: Arc<dyn std::any::Any + Send + Sync>,
70 ) -> Self {
71 Self {
72 db_pool,
73 app_context,
74 }
75 }
76
77 pub fn db_pool<T: 'static>(&self) -> Option<&T> {
78 self.db_pool.as_ref().downcast_ref::<T>()
79 }
80
81 pub fn app_context<T: 'static>(&self) -> Option<&T> {
82 self.app_context.as_ref().downcast_ref::<T>()
83 }
84
85 pub fn db_pool_arc(&self) -> Arc<dyn std::any::Any + Send + Sync> {
86 Arc::clone(&self.db_pool)
87 }
88
89 pub fn app_context_arc(&self) -> Arc<dyn std::any::Any + Send + Sync> {
90 Arc::clone(&self.app_context)
91 }
92}
93
94#[async_trait]
95pub trait Job: Send + Sync + 'static {
96 fn name(&self) -> &'static str;
97
98 fn description(&self) -> &'static str {
99 ""
100 }
101
102 fn schedule(&self) -> &'static str;
103
104 async fn execute(&self, ctx: &JobContext) -> Result<JobResult>;
105
106 fn enabled(&self) -> bool {
107 true
108 }
109
110 fn run_on_startup(&self) -> bool {
111 false
112 }
113}
114
115inventory::collect!(&'static dyn Job);
116
117#[macro_export]
118macro_rules! submit_job {
119 ($job:expr) => {
120 inventory::submit!($job as &'static dyn $crate::Job);
121 };
122}