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 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 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}