redis_batches/
lib.rs

1use once_cell::sync::Lazy;
2use redis::Script;
3use std::time::SystemTime;
4
5static LOCK_SCRIPT: Lazy<Script> =
6    Lazy::new(|| Script::new(include_str!("./redis_scripts/batches_lock.lua")));
7
8pub async fn lock(
9    key: &str,
10    field: &str,
11    lock_milli_second: u128,
12    redis_conn: &mut redis::aio::Connection,
13) -> Result<bool, redis::RedisError> {
14    let start_utsms = SystemTime::now()
15        .duration_since(SystemTime::UNIX_EPOCH)
16        .unwrap()
17        .as_millis();
18    let mut invocation = LOCK_SCRIPT.key(key);
19    invocation.key(field);
20    invocation.arg(start_utsms.to_string());
21    invocation.arg(lock_milli_second.to_string());
22    let res: Option<String> = invocation.invoke_async(redis_conn).await?;
23    Ok(res.is_some())
24}
25
26#[cfg(test)]
27mod tests {
28    use crate::lock;
29
30    #[tokio::test]
31    async fn it_works() {
32        let client = redis::Client::open("redis://127.0.0.1/").unwrap();
33        let mut con = client.get_async_connection().await.unwrap();
34        let res1 = lock("mutex", "test", 1000, &mut con).await.unwrap();
35        assert_eq!(true, res1);
36        let res2 = lock("mutex", "test", 1000, &mut con).await.unwrap();
37        assert_eq!(false, res2);
38        tokio::time::sleep(tokio::time::Duration::from_millis(1001)).await;
39        let res3 = lock("mutex", "test", 1000, &mut con).await.unwrap();
40        assert_eq!(true, res3);
41        tokio::time::sleep(tokio::time::Duration::from_millis(1001)).await;
42    }
43}