|
1 | 1 | use async_nats::jetstream; |
2 | 2 |
|
3 | 3 | use crate::{ |
4 | | - config::JobConfig, error::CronError, nats_impls::NatsConfigStore, traits::ConfigStore, |
| 4 | + config::JobConfig, domain::RegisteredJob, error::CronError, nats_impls::NatsConfigStore, |
| 5 | + traits::ConfigStore, |
5 | 6 | }; |
6 | 7 |
|
7 | 8 | /// Client for registering and managing CRON job configs. |
@@ -50,44 +51,12 @@ impl<C: ConfigStore> CronClient<C> { |
50 | 51 |
|
51 | 52 | /// Register or update a job. Existing jobs with the same `id` are overwritten. |
52 | 53 | /// |
53 | | - /// Structural constraints on `Action::Spawn` configs are validated here so |
54 | | - /// callers get an immediate error rather than a silent scheduler-side skip. |
55 | | - /// Filesystem checks (file exists, is executable) are intentionally omitted |
56 | | - /// because the client may run on a different host than the scheduler. |
| 54 | + /// Structural config constraints are validated here so callers get an |
| 55 | + /// immediate error rather than a silent scheduler-side skip. Filesystem |
| 56 | + /// checks for spawned binaries are intentionally omitted because the client |
| 57 | + /// may run on a different host than the scheduler. |
57 | 58 | pub async fn register_job(&self, config: &JobConfig) -> Result<(), CronError> { |
58 | | - if let crate::config::Action::Publish { subject } = &config.action { |
59 | | - if !subject.starts_with("cron.") { |
60 | | - return Err(CronError::InvalidJobConfig { |
61 | | - reason: format!("publish subject must start with 'cron.', got: {subject}"), |
62 | | - }); |
63 | | - } |
64 | | - } |
65 | | - if let crate::config::Action::Spawn { |
66 | | - bin, |
67 | | - args, |
68 | | - timeout_sec, |
69 | | - .. |
70 | | - } = &config.action |
71 | | - { |
72 | | - if !std::path::Path::new(bin).is_absolute() { |
73 | | - return Err(CronError::InvalidJobConfig { |
74 | | - reason: format!("bin must be an absolute path, got: {bin}"), |
75 | | - }); |
76 | | - } |
77 | | - for arg in args { |
78 | | - if arg.contains('\0') { |
79 | | - return Err(CronError::InvalidJobConfig { |
80 | | - reason: format!("argument contains null byte: {arg:?}"), |
81 | | - }); |
82 | | - } |
83 | | - } |
84 | | - if timeout_sec.is_some_and(|s| s == 0) { |
85 | | - return Err(CronError::InvalidJobConfig { |
86 | | - reason: "timeout_sec must be >= 1 when set".into(), |
87 | | - }); |
88 | | - } |
89 | | - } |
90 | | - |
| 59 | + let _ = RegisteredJob::try_from(config)?; |
91 | 60 | self.store.put_job(config).await?; |
92 | 61 | tracing::info!(job_id = %config.id, "Job registered"); |
93 | 62 | Ok(()) |
|
0 commit comments