#redis #distributed #locking #redlock #redis-server #dls

rslock

Implementation of the distributed locking mechanism built on top of Async Redis

11 releases (6 breaking)

1.0.0-alpha.1 Aug 31, 2023
0.6.0 Nov 18, 2024
0.5.1 Nov 18, 2024
0.4.0 Jun 18, 2024
0.0.4 Sep 26, 2022

#119 in Database interfaces

Download history 343/week @ 2024-08-02 752/week @ 2024-08-09 606/week @ 2024-08-16 930/week @ 2024-08-23 1047/week @ 2024-08-30 2284/week @ 2024-09-06 1359/week @ 2024-09-13 1367/week @ 2024-09-20 1269/week @ 2024-09-27 1267/week @ 2024-10-04 1017/week @ 2024-10-11 799/week @ 2024-10-18 863/week @ 2024-10-25 1417/week @ 2024-11-01 634/week @ 2024-11-08 973/week @ 2024-11-15

3,979 downloads per month

BSD-3-Clause

48KB
930 lines

rslock - Redlock for Redis in Rust

Crates.io Docs badge

This is an implementation of Redlock, the distributed locking mechanism built on top of Redis.

[!WARNING] Before release 1.0.0, this crate will have breaking changes between minor versions. You can upgrade to patch versions without worrying about breaking changes.

Features

  • Lock extending
  • Async runtime support (async-std and tokio)
  • Async redis

Install

cargo add rslock

[!NOTE] The default feature of this crate will provide async-std. You may optionally use tokio by supplying the tokio-comp feature flag when installing, but tokio has limitations that will not grant access to some parts of the API (read more here).

Build

cargo build --release

Usage

use std::time::Duration;

use rslock::LockManager;

#[tokio::main]
async fn main() {
    let rl = LockManager::new(vec![
        "redis://127.0.0.1:6380/",
        "redis://127.0.0.1:6381/",
        "redis://127.0.0.1:6382/",
    ]);

    let lock;
    loop {
        // Create the lock
        if let Ok(l) = rl
            .lock("mutex".as_bytes(), Duration::from_millis(1000))
            .await
        {
            lock = l;
            break;
        }
    }

    // Extend the lock
    match rl.extend(&lock, Duration::from_millis(1000)).await {
        Ok(_) => println!("lock extended!"),
        Err(_) => println!("lock couldn't be extended"),
    }

    // Unlock the lock
    rl.unlock(&lock).await;
}

Extending Locks

Extending a lock effectively renews its duration instead of adding extra time to it. For instance, if a 1000ms lock is extended by 1000ms after 500ms pass, it will only last for a total of 1500ms, not 2000ms. This approach is consistent with the Node.js Redlock implementation. See the extend script.

Tests

Run tests with:

cargo test

Examples

Start the redis servers mentioned in the example code:

docker compose -f examples/docker-compose.yml up -d

Run the examples:

cargo run --example basic
cargo run --example shared_lock

Stop the redis servers:

docker compose -f examples/docker-compose.yml down

Contribute

If you find bugs or want to help otherwise, please open an issue.

License

BSD. See LICENSE.

Dependencies

~7–18MB
~257K SLoC