pub struct Mutex<T> { /* private fields */ }Expand description
The RedisMutex struct.
It is used to lock a value in Redis, so that only one instance can access it at a time. You have to use RedisGeneric as the data type. It is a wrapper around the data type you want to store like the Mutex in std.
The lock is released when the guard is dropped or it expires. The default expiration time is 1000ms. If you need more time, use the Guard::expand() function.
Implementations§
Source§impl<T> Mutex<T>where
T: Serialize + DeserializeOwned,
impl<T> Mutex<T>where
T: Serialize + DeserializeOwned,
pub fn new(data: Generic<T>) -> Self
Sourcepub fn lock(&mut self) -> Result<Guard<'_, T>, LockError>
pub fn lock(&mut self) -> Result<Guard<'_, T>, LockError>
Locks the value in Redis. This function blocks until the lock is acquired. It returns a guard that can be used to access the value. The guard will unlock the value when it is dropped.
Beware that the value is not locked in the Rust sense and can be set by other instances, if they skip the locking process and its LOCK_SCRIPT.
If you try to lock a value that is already locked by another instance in the same scope, this function will block until the lock is released, which will be happen after the lock expires (1000ms). If you need to extend this time, you can use the Guard::expand() function.
§Example
use dtypes::redis::types::Di32 as i32;
use dtypes::redis::sync::Mutex;
use std::thread::scope;
let client = redis::Client::open("redis://localhost:6379").unwrap();
let client2 = client.clone();
scope(|s| {
let t1 = s.spawn(move || {
let mut i32 = i32::new("test_add_example1", client2);
let mut lock = Mutex::new(i32);
let mut guard = lock.lock().unwrap();
guard.store(2).expect("TODO: panic message");
assert_eq!(*guard, 2);
});
{
let mut i32 = i32::new("test_add_example1", client);
let mut lock = Mutex::new(i32);
let mut guard = lock.lock().unwrap();
guard.store(1).expect("Failed to store value");
assert_eq!(*guard, 1);
}
t1.join().expect("Failed to join thread1");
});It does not allow any deadlocks, because the lock will automatically release after some time. So you have to check for errors, if you want to handle them.
Beware: Your CPU can anytime switch to another thread, so you have to check for errors! But if you are brave enough, you can drop the result and hope for the best.
§Example
use std::thread::sleep;
use dtypes::redis::types::Di32 as i32;
use dtypes::redis::sync::Mutex;
let client = redis::Client::open("redis://localhost:6379").unwrap();
let mut i32 = i32::new("test_add_example2", client.clone());
i32.store(1);
assert_eq!(i32.acquire(), &1);
let mut lock = Mutex::new(i32);
let mut guard = lock.lock().unwrap();
sleep(std::time::Duration::from_millis(1500));
let res = guard.store(3);
assert!(res.is_err(), "{:?}", res);Methods from Deref<Target = Generic<T>>§
Sourcepub fn store(&mut self, value: T)
pub fn store(&mut self, value: T)
The store method sets the value of the type.
Examples found in repository?
5fn main() {
6 thread::scope(|s| {
7 let client = redis::Client::open("redis://localhost:6379").unwrap();
8 let client2 = client.clone();
9
10 let t1 = s.spawn(move || {
11 let mut string = String::with_value("Hello".to_string(), "test", client);
12 println!("Thread1: {}", string.cached().unwrap());
13 assert_eq!(string, "Hello");
14 sleep(std::time::Duration::from_secs(1));
15 string.store("World".to_string());
16 println!("Thread1: {}", string.cached().unwrap());
17 assert_eq!(string, "World");
18 });
19
20 let t2 = s.spawn(move || {
21 sleep(std::time::Duration::from_micros(100));
22 let mut string = String::with_load("test", client2);
23 println!("Thread2: {}", string.cached().unwrap());
24 assert_eq!(string, "Hello");
25 sleep(std::time::Duration::from_secs(2));
26 string.acquire();
27 println!("Thread2: {}", string.cached().unwrap());
28 assert_eq!(string, "World");
29 });
30 t1.join().expect("Failed to join thread1");
31 t2.join().expect("Failed to join thread2");
32 });
33}Sourcepub fn acquire(&mut self) -> &T
pub fn acquire(&mut self) -> &T
The acquire method returns a reference to the value stored in the type. Loads it from the redis directly.
§Example
use dtypes::redis::types::Di32 as i32;
let client = redis::Client::open("redis://localhost:6379").unwrap();
let mut i32 = i32::with_value(1, "test_add", client.clone());
i32 = i32 + i32::with_value(2, "test_add2", client);
assert_eq!(i32.acquire(), &3);Examples found in repository?
5fn main() {
6 thread::scope(|s| {
7 let client = redis::Client::open("redis://localhost:6379").unwrap();
8 let client2 = client.clone();
9
10 let t1 = s.spawn(move || {
11 let mut string = String::with_value("Hello".to_string(), "test", client);
12 println!("Thread1: {}", string.cached().unwrap());
13 assert_eq!(string, "Hello");
14 sleep(std::time::Duration::from_secs(1));
15 string.store("World".to_string());
16 println!("Thread1: {}", string.cached().unwrap());
17 assert_eq!(string, "World");
18 });
19
20 let t2 = s.spawn(move || {
21 sleep(std::time::Duration::from_micros(100));
22 let mut string = String::with_load("test", client2);
23 println!("Thread2: {}", string.cached().unwrap());
24 assert_eq!(string, "Hello");
25 sleep(std::time::Duration::from_secs(2));
26 string.acquire();
27 println!("Thread2: {}", string.cached().unwrap());
28 assert_eq!(string, "World");
29 });
30 t1.join().expect("Failed to join thread1");
31 t2.join().expect("Failed to join thread2");
32 });
33}Sourcepub fn cached(&self) -> Option<&T>
pub fn cached(&self) -> Option<&T>
The get method returns a reference to the value stored in the type.
Examples found in repository?
5fn main() {
6 thread::scope(|s| {
7 let client = redis::Client::open("redis://localhost:6379").unwrap();
8 let client2 = client.clone();
9
10 let t1 = s.spawn(move || {
11 let mut string = String::with_value("Hello".to_string(), "test", client);
12 println!("Thread1: {}", string.cached().unwrap());
13 assert_eq!(string, "Hello");
14 sleep(std::time::Duration::from_secs(1));
15 string.store("World".to_string());
16 println!("Thread1: {}", string.cached().unwrap());
17 assert_eq!(string, "World");
18 });
19
20 let t2 = s.spawn(move || {
21 sleep(std::time::Duration::from_micros(100));
22 let mut string = String::with_load("test", client2);
23 println!("Thread2: {}", string.cached().unwrap());
24 assert_eq!(string, "Hello");
25 sleep(std::time::Duration::from_secs(2));
26 string.acquire();
27 println!("Thread2: {}", string.cached().unwrap());
28 assert_eq!(string, "World");
29 });
30 t1.join().expect("Failed to join thread1");
31 t2.join().expect("Failed to join thread2");
32 });
33}