#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

#118 in Database interfaces

Download history 1009/week @ 2024-08-25 1157/week @ 2024-09-01 2419/week @ 2024-09-08 1076/week @ 2024-09-15 1383/week @ 2024-09-22 1280/week @ 2024-09-29 1305/week @ 2024-10-06 926/week @ 2024-10-13 737/week @ 2024-10-20 978/week @ 2024-10-27 1304/week @ 2024-11-03 800/week @ 2024-11-10 924/week @ 2024-11-17 1184/week @ 2024-11-24 1459/week @ 2024-12-01 2542/week @ 2024-12-08

6,164 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–20MB
~270K SLoC