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::sync::RwLock;
use dtypes::redis::types::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::sync::RwLock;
use dtypes::redis::types::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?
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}