#![allow(dead_code)]
use std::sync::OnceLock;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use redis::aio::ConnectionManager;
use crate::lock::DEFAULT_LOCK_NAMESPACE;
use crate::{DistkitRedisKey, lock::LockOptions};
static RUN_ID: OnceLock<u128> = OnceLock::new();
fn run_id() -> u128 {
*RUN_ID.get_or_init(|| {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos()
})
}
pub async fn raw_connection() -> ConnectionManager {
let url = std::env::var("REDIS_URL").expect("REDIS_URL must be set — run via `make test`");
let client = redis::Client::open(url).expect("valid Redis URL");
client
.get_connection_manager()
.await
.expect("Redis must be reachable")
}
pub async fn make_options(name: &str) -> LockOptions {
make_options_with_key(name).await.0
}
pub async fn make_options_with_key(name: &str) -> (LockOptions, String) {
let conn = raw_connection().await;
let unique_key = format!("{}_{}", run_id(), name);
let full_key = format!("{DEFAULT_LOCK_NAMESPACE}:{unique_key}");
let options = LockOptions::new(DistkitRedisKey::from(unique_key), conn);
(options, full_key)
}
pub async fn make_fast_options(name: &str) -> LockOptions {
let mut options = make_options(name).await;
options.retry_interval = Duration::from_millis(20);
options
}
pub fn key(name: &str) -> DistkitRedisKey {
DistkitRedisKey::from(name.to_string())
}
pub struct RwKeys {
pub writer: String,
pub readers: String,
pub pending: String,
pub pending_heartbeat: String,
}
pub async fn make_options_with_rw_keys(name: &str) -> (LockOptions, RwKeys) {
let (options, base) = make_options_with_key(name).await;
let keys = RwKeys {
writer: format!("{base}:w"),
readers: format!("{base}:r"),
pending: format!("{base}:pw"),
pending_heartbeat: format!("{base}:pwh"),
};
(options, keys)
}