Skip to main content

rrq_config/
settings.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5use crate::cron::CronJob;
6use crate::defaults::{
7    DEFAULT_DLQ_NAME, DEFAULT_EXPECTED_JOB_TTL, DEFAULT_JOB_TIMEOUT_SECONDS,
8    DEFAULT_LOCK_TIMEOUT_EXTENSION_SECONDS, DEFAULT_MAX_RETRIES, DEFAULT_POLL_DELAY_SECONDS,
9    DEFAULT_QUEUE_NAME, DEFAULT_REDIS_DSN, DEFAULT_RESULT_TTL_SECONDS,
10    DEFAULT_RUNNER_CONNECT_TIMEOUT_MS, DEFAULT_UNIQUE_JOB_LOCK_TTL_SECONDS,
11};
12
13#[derive(Debug, Clone, Serialize, Deserialize, Default)]
14#[serde(rename_all = "snake_case")]
15pub enum RunnerType {
16    #[default]
17    Socket,
18}
19
20#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default, PartialEq, Eq)]
21#[serde(rename_all = "snake_case")]
22pub enum RunnerManagementMode {
23    #[default]
24    Managed,
25    External,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize, Default)]
29#[serde(deny_unknown_fields)]
30pub struct RunnerConfig {
31    #[serde(default = "default_runner_type", rename = "type")]
32    pub runner_type: RunnerType,
33    pub cmd: Option<Vec<String>>,
34    pub pool_size: Option<usize>,
35    pub max_in_flight: Option<usize>,
36    pub env: Option<HashMap<String, String>>,
37    pub cwd: Option<String>,
38    pub tcp_host: Option<String>,
39    pub tcp_port: Option<u16>,
40    pub allowed_hosts: Option<Vec<String>>,
41    pub response_timeout_seconds: Option<f64>,
42}
43
44fn default_runner_type() -> RunnerType {
45    RunnerType::Socket
46}
47
48#[derive(Debug, Clone, Serialize, Deserialize, Default)]
49#[serde(rename_all = "snake_case", default)]
50pub struct WatchSettings {
51    pub path: Option<String>,
52    pub include_patterns: Vec<String>,
53    pub ignore_patterns: Vec<String>,
54    pub no_gitignore: Option<bool>,
55    /// Optional commands to run before starting/restarting a worker in watch mode.
56    /// Each entry is an argv array: `["cmd", "arg1", ...]`.
57    pub pre_restart_cmds: Vec<Vec<String>>,
58    /// Optional working directory for `pre_restart_cmds`.
59    /// Defaults to the resolved watch root.
60    pub pre_restart_cwd: Option<String>,
61    /// Optional timeout (seconds) applied to each `pre_restart_cmds` entry.
62    pub pre_restart_timeout_seconds: Option<f64>,
63}
64
65#[derive(Debug, Clone, Serialize, Deserialize)]
66#[serde(rename_all = "snake_case", default)]
67pub struct RRQSettings {
68    pub redis_dsn: String,
69    pub default_queue_name: String,
70    pub default_dlq_name: String,
71    pub default_max_retries: i64,
72    pub default_job_timeout_seconds: i64,
73    pub default_lock_timeout_extension_seconds: i64,
74    pub default_result_ttl_seconds: i64,
75    pub default_poll_delay_seconds: f64,
76    pub runner_connect_timeout_ms: i64,
77    /// Grace period after SIGTERM before escalating to SIGKILL for runner processes.
78    pub runner_shutdown_term_grace_seconds: f64,
79    /// Whether to send in-flight cancel protocol messages as best-effort hints.
80    pub runner_enable_inflight_cancel_hints: bool,
81    /// When true, capture runner stdout/stderr and re-emit through rrq's
82    /// structured logging.  When false (default), runner output goes directly
83    /// to the terminal.  Enable in production for unified log shipping.
84    pub capture_runner_output: bool,
85    pub default_unique_job_lock_ttl_seconds: i64,
86    pub default_runner_name: String,
87    pub runner_management_mode: RunnerManagementMode,
88    pub runners: HashMap<String, RunnerConfig>,
89    pub runner_routes: HashMap<String, String>,
90    pub worker_health_check_interval_seconds: f64,
91    pub worker_health_check_ttl_buffer_seconds: f64,
92    pub base_retry_delay_seconds: f64,
93    pub max_retry_delay_seconds: f64,
94    pub worker_shutdown_grace_period_seconds: f64,
95    pub cron_jobs: Vec<CronJob>,
96    pub expected_job_ttl: i64,
97    pub watch: WatchSettings,
98    pub correlation_mappings: HashMap<String, String>,
99}
100
101impl Default for RRQSettings {
102    fn default() -> Self {
103        Self {
104            redis_dsn: DEFAULT_REDIS_DSN.to_string(),
105            default_queue_name: DEFAULT_QUEUE_NAME.to_string(),
106            default_dlq_name: DEFAULT_DLQ_NAME.to_string(),
107            default_max_retries: DEFAULT_MAX_RETRIES,
108            default_job_timeout_seconds: DEFAULT_JOB_TIMEOUT_SECONDS,
109            default_lock_timeout_extension_seconds: DEFAULT_LOCK_TIMEOUT_EXTENSION_SECONDS,
110            default_result_ttl_seconds: DEFAULT_RESULT_TTL_SECONDS,
111            default_poll_delay_seconds: DEFAULT_POLL_DELAY_SECONDS,
112            runner_connect_timeout_ms: DEFAULT_RUNNER_CONNECT_TIMEOUT_MS,
113            runner_shutdown_term_grace_seconds: 5.0,
114            runner_enable_inflight_cancel_hints: false,
115            capture_runner_output: false,
116            default_unique_job_lock_ttl_seconds: DEFAULT_UNIQUE_JOB_LOCK_TTL_SECONDS,
117            default_runner_name: "python".to_string(),
118            runner_management_mode: RunnerManagementMode::Managed,
119            runners: HashMap::new(),
120            runner_routes: HashMap::new(),
121            worker_health_check_interval_seconds: 60.0,
122            worker_health_check_ttl_buffer_seconds: 10.0,
123            base_retry_delay_seconds: 5.0,
124            max_retry_delay_seconds: 60.0 * 60.0,
125            worker_shutdown_grace_period_seconds: 10.0,
126            cron_jobs: Vec::new(),
127            expected_job_ttl: DEFAULT_EXPECTED_JOB_TTL,
128            watch: WatchSettings::default(),
129            correlation_mappings: HashMap::new(),
130        }
131    }
132}