ghetto-lock

Crates.ioghetto-lock
lib.rsghetto-lock
version0.2.1
sourcesrc
created_at2019-12-18 17:01:56.464413
updated_at2019-12-29 16:11:48.519191
descriptionMemcache backed ghetto lock implementation
homepage
repositoryhttps://github.com/letmutx/ghetto-lock-rs.git
max_upload_size
id190341
size20,811
(letmutx)

documentation

README

ghetto-lock

Build Status

NOTE: This crate has been moved to https://crates.io/crates/macgyver-lock

This library implements the ghetto lock described here. The lock isn't resistant to server failures and should be used only in situations where strong locking guarantees are not required.

A popular use case for this lock is to avoid the stampeding herd problem caused by a cache miss.

Usage:

Add to your Cargo.toml:

ghetto-lock = "0.2.0"

Example:

use ghetto_lock::{LockOptions, LockError};
use memcache::Client;
use std::borrow::Cow;

fn expensive_computation() -> u64 {
    2 * 2
}

fn main() {
    let mut client = Client::connect("memcache://localhost:11211").expect("error creating client");
    let mut lock = LockOptions::new(Cow::Borrowed("db-lock"), Cow::Borrowed("owner-1"))
                    .with_expiry(1)
                    .build()
                    .expect("failed to build client");
    let value = client.get("key").expect("failed to get key");
    let v = if value.is_none() {
        lock.try_acquire()
            .and_then(|_guard| {
                // compute and update cache for other instances to consume
                let v = expensive_computation();
                client.set("key", v, 5).expect("failed to set key");
                Ok(v)
            })
            .or_else(|_| loop {
                // poll cache key until it is updated.
                let v = client.get("key").expect("failed to get key");
                if v.is_none() {
                    continue;
                }
                break Ok::<_, LockError>(v.unwrap());
            }).unwrap()
    } else { value.unwrap() };
    assert_eq!(4, v);
}
Commit count: 38

cargo fmt