AppConfig
Basic Usage
Section titled “Basic Usage”use horsies::{ Horsies, AppConfig,};
let config = AppConfig::for_database_url("postgresql://user:pass@localhost:5432/mydb");let mut app = Horsies::new(config)?;Fields
Section titled “Fields”| Field | Type | Default | Description |
|---|---|---|---|
queue_mode | QueueMode | Default | Queue operating mode |
custom_queues | Option<Vec<CustomQueueConfig>> | None | Queue definitions (Custom mode only) |
broker | PostgresConfig | required | Database connection settings |
cluster_wide_cap | Option<u32> | None | Max in-flight tasks cluster-wide |
prefetch_buffer | u32 | 0 | 0 = hard cap mode, >0 = soft cap with prefetch |
claim_lease_ms | Option<u32> | None | Claim lease duration (required if prefetch_buffer > 0; optional override in hard cap mode) |
max_claim_renew_age_ms | u32 | 180000 | Max age (ms) of a CLAIMED task that heartbeat will renew. Older claims are left to expire, preventing indefinite renewal of orphaned tasks. Must be >= effective claim lease |
recovery | RecoveryConfig | defaults | Crash recovery settings |
resilience | WorkerResilienceConfig | defaults | Worker retry/backoff and notify polling |
schedule | Option<ScheduleConfig> | None | Scheduled task configuration |
resend_on_transient_err | bool | false | Auto-retry transient enqueue/start failures for task sends, scheduled sends, and workflow starts |
Queue Mode Configuration
Section titled “Queue Mode Configuration”DEFAULT Mode
Section titled “DEFAULT Mode”let config = AppConfig { queue_mode: QueueMode::Default, custom_queues: None, ..AppConfig::for_database_url("postgresql://...")};CUSTOM Mode
Section titled “CUSTOM Mode”use horsies::CustomQueueConfig;
let config = AppConfig { queue_mode: QueueMode::Custom, custom_queues: Some(vec![ CustomQueueConfig { name: "high".into(), priority: 1, max_concurrency: 10 }, CustomQueueConfig { name: "low".into(), priority: 100, max_concurrency: 3 }, ]), ..AppConfig::for_database_url("postgresql://...")};See Queue Modes for details.
Cluster-Wide Concurrency
Section titled “Cluster-Wide Concurrency”Limit total in-flight tasks across all workers:
let config = AppConfig { cluster_wide_cap: Some(100), // Max 100 in-flight tasks (RUNNING + CLAIMED) ..AppConfig::for_database_url("postgresql://...")};Set to None (default) for unlimited.
Note: When cluster_wide_cap is set, the system operates in hard cap mode (counts RUNNING + CLAIMED tasks). This ensures strict enforcement and fair distribution across workers.
Prefetch Configuration
Section titled “Prefetch Configuration”Control whether workers can prefetch tasks beyond their running capacity:
// Hard cap mode (default) - strict enforcement, fair distributionlet config = AppConfig { prefetch_buffer: 0, // No prefetch, workers only claim what they can run ..AppConfig::for_database_url("postgresql://...")};
// Soft cap mode - allows prefetch with lease expirylet config = AppConfig { prefetch_buffer: 4, // Prefetch up to 4 extra tasks per worker claim_lease_ms: Some(5000), // Prefetched claims expire after 5 seconds ..AppConfig::for_database_url("postgresql://...")};Important: cluster_wide_cap cannot be used with prefetch_buffer > 0. If you need a global cap, hard cap mode is required.
See Concurrency for detailed explanation of hard vs soft cap modes.
Recovery Configuration
Section titled “Recovery Configuration”Override crash recovery defaults:
use horsies::RecoveryConfig;
let config = AppConfig { recovery: RecoveryConfig { auto_requeue_stale_claimed: true, claimed_stale_threshold_ms: 120_000, // 2 minutes auto_fail_stale_running: true, running_stale_threshold_ms: 300_000, // 5 minutes ..RecoveryConfig::default() }, ..AppConfig::for_database_url("postgresql://...")};See Recovery Config for all options.
Resilience Configuration
Section titled “Resilience Configuration”Configure worker retry/backoff and NOTIFY fallback polling:
use horsies::WorkerResilienceConfig;
let config = AppConfig { resilience: WorkerResilienceConfig { db_retry_initial_ms: 500, db_retry_max_ms: 30_000, db_retry_max_attempts: 0, // 0 = infinite notify_poll_interval_ms: 5_000, }, ..AppConfig::for_database_url("postgresql://...")};Schedule Configuration
Section titled “Schedule Configuration”Enable scheduled tasks:
use horsies::{ScheduleConfig, TaskSchedule, SchedulePattern, DailySchedule};use chrono::NaiveTime;
let config = AppConfig { schedule: Some(ScheduleConfig::new(vec![ TaskSchedule::new( "daily-cleanup", "cleanup_old_data", SchedulePattern::Daily(DailySchedule { time: NaiveTime::from_hms_opt(3, 0, 0).unwrap(), }), ), ])), ..AppConfig::for_database_url("postgresql://...")};See Scheduler Overview for details.
Validation
Section titled “Validation”AppConfig is validated when you construct Horsies or run app.check():
- CUSTOM mode requires non-empty
custom_queues - DEFAULT mode must not have
custom_queues - Queue names must be unique
cluster_wide_capmust be positive if setprefetch_buffermust be non-negativeclaim_lease_msis required whenprefetch_buffer > 0claim_lease_msis optional whenprefetch_buffer = 0(overrides the default 60s lease)cluster_wide_capcannot be combined withprefetch_buffer > 0
Multiple validation errors within the same phase are collected and reported together (compiler-style), rather than stopping at the first error.
Startup Validation (app.check())
Section titled “Startup Validation (app.check())”Use app.check() to run static validation before starting a worker or scheduler. Use app.check_live() to additionally connect to PostgreSQL, ensure the schema, and verify broker connectivity.
// Static validation — returns Result<(), HorsiesError>app.check()?;
// Static + broker connectivity checkapp.check_live().await?;Phases:
| Phase | What it validates | Gating |
|---|---|---|
| 1. Config | AppConfig, RecoveryConfig, ScheduleConfig consistency | Validated at construction (implicit pass) |
| 2. Task registry | All registered tasks have valid names and queue assignments | Errors stop progression to later phases |
| 3. Workflows | WorkflowSpec DAG validation (cycles, missing deps, type mismatches) | Collected alongside Phase 2 |
4. Broker (if check_live) | Connects to PostgreSQL, ensures the Horsies schema, and runs SELECT 1 | Only runs if earlier phases pass |
Returns Ok(()) when all validations pass, or Err(HorsiesError) with diagnostic messages.
CLI equivalent:
horsies check ./config/horsies.toml # Static validationhorsies check ./config/horsies.toml --live # Static + broker connectivityLogging Configuration
Section titled “Logging Configuration”Log the configuration (with masked password):
use tracing::info;
info!("AppConfig:\n{}", config.format_for_logging());Output:
AppConfig: queue_mode: DEFAULT broker: database_url: postgresql://user:***@localhost/db pool_size: 30 max_overflow: 30 recovery: auto_requeue_stale_claimed: true ...