pub struct RwLock<T> { /* private fields */ }Expand description
A Read-Write Lock.
This lock is similar to the std::sync::RwLock. But it is distributed over multiple instances of the same service.
Threads
If you try to get a writer lock in a thread, which already has a reader lock, you will end up in a deadlock. To use the RwLock in threads, you need a scoped thread.
Examples
Linear usage
use dtypes::redis::RwLock;
use dtypes::redis::Di32;
use std::thread;
let client = redis::Client::open("redis://localhost:6379").unwrap();
let client2 = client.clone();
let mut i32 = Di32::with_value(1, "test_rwlock_example1", client.clone());
let mut lock = RwLock::new(i32);
// many reader locks can be held at once
{
let read1 = lock.read().unwrap();
let read2 = lock.read().unwrap();
assert_eq!(*read1, 1);
} // read locks are dropped at this point
// only one writer lock can be held, however
{
let mut write1 = lock.write().unwrap();
write1.store(2).unwrap();
assert_eq!(*write1, 2);
// the next line is not allowed, because it deadlocks.
//let mut _ = lock.write().unwrap();
} // write lock is dropped here
// look, you can read it again
{
let read1 = lock.read().unwrap();
assert_eq!(*read1, 2);
}Threaded usage
use dtypes::redis::RwLock;
use dtypes::redis::Di32;
use std::thread;
let client = redis::Client::open("redis://localhost:6379").unwrap();
let i32 = Di32::with_value(1, "test_rwlock_example2", client.clone());
let mut lock = RwLock::new(i32);
// the reader lock is dropped immediately
assert_eq!(*lock.read().unwrap(), 1);
// Scoped threads are needed, otherwise the lifetime is unclear.
thread::scope(|s| {
s.spawn(|| {
let mut write = lock.write().unwrap();
write.store(2);
assert_eq!(*write, 2);
}).join().unwrap();
});
assert_eq!(*lock.read().unwrap(), 2);Implementations§
source§impl<T> RwLock<T>where
T: Serialize + DeserializeOwned,
impl<T> RwLock<T>where T: Serialize + DeserializeOwned,
pub fn new(data: Generic<T>) -> Self
sourcepub fn read(&self) -> Result<RwLockReadGuard<'_, T>, LockError>
pub fn read(&self) -> Result<RwLockReadGuard<'_, T>, LockError>
Creates a new RwLock Reader.
This function blocks until the lock is acquired. If there is a writer lock, this function blocks until the writer lock is dropped. Also if there is a writer locks waiting to be acquired, this function blocks until the writer lock is acquired and dropped.
sourcepub fn write(&mut self) -> Result<RwLockWriteGuard<'_, T>, LockError>
pub fn write(&mut self) -> Result<RwLockWriteGuard<'_, T>, LockError>
Creates a new RwLock Writer.
This function blocks until the lock is acquired. If there is a reader lock, this function blocks until the reader lock is dropped. The acquiring writer lock has priority over any waiting reader lock.
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?
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
fn main() {
thread::scope(|s| {
let client = redis::Client::open("redis://localhost:6379").unwrap();
let client2 = client.clone();
let t1 = s.spawn(move || {
let mut string = String::with_value("Hello".to_string(), "test", client);
println!("Thread1: {}", string.cached().unwrap());
assert_eq!(string, "Hello");
sleep(std::time::Duration::from_secs(1));
string.store("World".to_string());
println!("Thread1: {}", string.cached().unwrap());
assert_eq!(string, "World");
});
let t2 = s.spawn(move || {
sleep(std::time::Duration::from_micros(100));
let mut string = String::with_load("test", client2);
println!("Thread2: {}", string.cached().unwrap());
assert_eq!(string, "Hello");
sleep(std::time::Duration::from_secs(2));
string.acquire();
println!("Thread2: {}", string.cached().unwrap());
assert_eq!(string, "World");
});
t1.join().expect("Failed to join thread1");
t2.join().expect("Failed to join thread2");
});
}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::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?
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
fn main() {
thread::scope(|s| {
let client = redis::Client::open("redis://localhost:6379").unwrap();
let client2 = client.clone();
let t1 = s.spawn(move || {
let mut string = String::with_value("Hello".to_string(), "test", client);
println!("Thread1: {}", string.cached().unwrap());
assert_eq!(string, "Hello");
sleep(std::time::Duration::from_secs(1));
string.store("World".to_string());
println!("Thread1: {}", string.cached().unwrap());
assert_eq!(string, "World");
});
let t2 = s.spawn(move || {
sleep(std::time::Duration::from_micros(100));
let mut string = String::with_load("test", client2);
println!("Thread2: {}", string.cached().unwrap());
assert_eq!(string, "Hello");
sleep(std::time::Duration::from_secs(2));
string.acquire();
println!("Thread2: {}", string.cached().unwrap());
assert_eq!(string, "World");
});
t1.join().expect("Failed to join thread1");
t2.join().expect("Failed to join thread2");
});
}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?
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
fn main() {
thread::scope(|s| {
let client = redis::Client::open("redis://localhost:6379").unwrap();
let client2 = client.clone();
let t1 = s.spawn(move || {
let mut string = String::with_value("Hello".to_string(), "test", client);
println!("Thread1: {}", string.cached().unwrap());
assert_eq!(string, "Hello");
sleep(std::time::Duration::from_secs(1));
string.store("World".to_string());
println!("Thread1: {}", string.cached().unwrap());
assert_eq!(string, "World");
});
let t2 = s.spawn(move || {
sleep(std::time::Duration::from_micros(100));
let mut string = String::with_load("test", client2);
println!("Thread2: {}", string.cached().unwrap());
assert_eq!(string, "Hello");
sleep(std::time::Duration::from_secs(2));
string.acquire();
println!("Thread2: {}", string.cached().unwrap());
assert_eq!(string, "World");
});
t1.join().expect("Failed to join thread1");
t2.join().expect("Failed to join thread2");
});
}