job/
config.rs

1use derive_builder::Builder;
2use serde::{Deserialize, Serialize};
3
4use std::time::Duration;
5
6#[serde_with::serde_as]
7#[derive(Clone, Debug, Serialize, Deserialize)]
8pub struct JobPollerConfig {
9    #[serde_as(as = "serde_with::DurationSeconds<u64>")]
10    #[serde(default = "default_job_lost_interval")]
11    pub job_lost_interval: Duration,
12    #[serde(default = "default_max_jobs_per_process")]
13    pub max_jobs_per_process: usize,
14    #[serde(default = "default_min_jobs_per_process")]
15    pub min_jobs_per_process: usize,
16}
17
18impl Default for JobPollerConfig {
19    fn default() -> Self {
20        Self {
21            job_lost_interval: default_job_lost_interval(),
22            max_jobs_per_process: default_max_jobs_per_process(),
23            min_jobs_per_process: default_min_jobs_per_process(),
24        }
25    }
26}
27
28#[derive(Builder, Debug, Clone)]
29#[builder(build_fn(skip))]
30pub struct JobSvcConfig {
31    #[builder(setter(into, strip_option), default)]
32    pub(super) pg_con: Option<String>,
33    #[builder(setter(into, strip_option), default)]
34    pub(super) max_connections: Option<u32>,
35    #[builder(default)]
36    pub(super) exec_migrations: bool,
37    #[builder(setter(into, strip_option), default)]
38    pub(super) pool: Option<sqlx::PgPool>,
39    #[builder(default)]
40    pub process_config: JobPollerConfig,
41}
42
43impl JobSvcConfig {
44    pub fn builder() -> JobSvcConfigBuilder {
45        JobSvcConfigBuilder::default()
46    }
47}
48
49impl JobSvcConfigBuilder {
50    pub fn build(&mut self) -> Result<JobSvcConfig, String> {
51        // Validate configuration
52        match (self.pg_con.as_ref(), self.pool.as_ref()) {
53            (None, None) | (Some(None), None) | (None, Some(None)) => {
54                return Err("One of pg_con or pool must be set".to_string());
55            }
56            (Some(_), Some(_)) => return Err("Only one of pg_con or pool must be set".to_string()),
57            _ => (),
58        }
59
60        // If pg_con is provided and exec_migrations is not explicitly set, default to true
61        if matches!(self.pg_con.as_ref(), Some(Some(_))) && self.exec_migrations.is_none() {
62            self.exec_migrations = Some(true);
63        }
64
65        Ok(JobSvcConfig {
66            pg_con: self.pg_con.clone().flatten(),
67            max_connections: self.max_connections.flatten(),
68            exec_migrations: self.exec_migrations.unwrap_or(false),
69            pool: self.pool.clone().flatten(),
70            process_config: self.process_config.clone().unwrap_or_default(),
71        })
72    }
73}
74
75fn default_job_lost_interval() -> Duration {
76    Duration::from_secs(60 * 5)
77}
78
79fn default_max_jobs_per_process() -> usize {
80    50
81}
82
83fn default_min_jobs_per_process() -> usize {
84    30
85}