use xxhash_rust::xxh64::xxh64;
pub fn partition_index_for_job_id(job_id: &str, num_partitions: u32) -> u32 {
let n = num_partitions.max(1);
let h = xxh64(job_id.as_bytes(), 0);
(h % u64::from(n)) as u32
}
pub fn partition_hash_i64_for_job_id(job_id: &str) -> i64 {
i64::from(partition_index_for_job_id(job_id, num_partitions_from_env()))
}
pub const DEFAULT_POOL: &str = "general";
pub fn job_execution_pool_id(job: &chronon_core::Job) -> String {
job.pool
.as_ref()
.map(|s| s.trim().to_string())
.filter(|s| !s.is_empty())
.unwrap_or_else(|| DEFAULT_POOL.to_string())
}
const DEFAULT_NUM_PARTITIONS: u32 = 64;
const DEFAULT_TICK_INTERVAL_MS: u64 = 250;
pub fn num_partitions_from_env() -> u32 {
std::env::var("CHRONON_NUM_PARTITIONS")
.ok()
.and_then(|s| s.parse::<u32>().ok())
.filter(|&n| n >= 1)
.unwrap_or(DEFAULT_NUM_PARTITIONS)
}
pub fn tick_interval_ms_from_env() -> u64 {
std::env::var("CHRONON_TICK_INTERVAL_MS")
.ok()
.and_then(|s| s.parse::<u64>().ok())
.filter(|&n| n >= 1)
.unwrap_or(DEFAULT_TICK_INTERVAL_MS)
}
pub fn tick_batch_limit_from_env() -> u32 {
std::env::var("CHRONON_TICK_BATCH_LIMIT")
.ok()
.and_then(|s| s.parse::<u32>().ok())
.filter(|&n| n >= 1)
.unwrap_or(500)
}
pub fn job_claim_lease_ttl_secs() -> i64 {
std::env::var("CHRONON_JOB_CLAIM_LEASE_TTL_S")
.ok()
.and_then(|s| s.parse::<i64>().ok())
.filter(|&n| n >= 1)
.unwrap_or(5)
}
pub fn partition_lease_ttl_secs() -> i64 {
std::env::var("CHRONON_PARTITION_LEASE_TTL_S")
.ok()
.and_then(|s| s.parse::<i64>().ok())
.filter(|&n| n >= 1)
.unwrap_or(30)
}
pub fn partition_lease_renew_interval_secs() -> u64 {
std::env::var("CHRONON_PARTITION_LEASE_RENEW_S")
.ok()
.and_then(|s| s.parse::<u64>().ok())
.filter(|&n| n >= 1)
.unwrap_or(5)
}
pub fn run_worker_lease_ttl_secs() -> i64 {
std::env::var("CHRONON_RUN_LEASE_TTL_S")
.ok()
.and_then(|s| s.parse::<i64>().ok())
.filter(|&n| n >= 1)
.unwrap_or(300)
}
pub fn run_worker_lease_renew_secs() -> u64 {
std::env::var("CHRONON_RUN_LEASE_RENEW_S")
.ok()
.and_then(|s| s.parse::<u64>().ok())
.filter(|&n| n >= 1)
.unwrap_or(1)
}
pub fn worker_pool_from_env() -> String {
std::env::var("CHRONON_WORKER_POOL").unwrap_or_else(|_| "general".to_string())
}
pub fn worker_concurrency_from_env() -> usize {
std::env::var("CHRONON_WORKER_CONCURRENCY")
.ok()
.and_then(|s| s.parse::<usize>().ok())
.filter(|&n| n >= 1)
.unwrap_or(4)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn partition_stable_for_same_job() {
let a = partition_index_for_job_id("job-1", 64);
let b = partition_index_for_job_id("job-1", 64);
assert_eq!(a, b);
}
#[test]
fn partition_in_range() {
for i in 0..1000u32 {
let id = format!("jid-{i}");
let p = partition_index_for_job_id(&id, 64);
assert!(p < 64);
}
}
}