macgyver-lock

Crates.iomacgyver-lock
lib.rsmacgyver-lock
version0.2.0
sourcesrc
created_at2019-12-29 16:07:05.645496
updated_at2019-12-29 16:07:05.645496
descriptionMemcache backed lock implementation
homepage
repositoryhttps://github.com/letmutx/macgyver-lock-rs.git
max_upload_size
id193263
size20,785
(letmutx)

documentation

README

macgyver-lock

Build Status

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:

macgyver-lock = "0.1.0"

Example:

use macgyver_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