pub struct ClockOrdered<T> { /* private fields */ }Expand description
The ClockOrdered type.
It is used to store a value in redis and load it in sync. It tracks automatically an ordering number to ensure that the value is only stored if the order is greater than the current order, mostly from other instances. The value is only stored if the order is greater than the current order.
This helps to synchronize the value between multiple instances without any locking mechanism. But can results in more network traffic in benefit of less wait time because of locks. Mostly used in situations, where your value changes rarely but read often. Another use case is, when it is okay for you, that the value could be not the latest or computing a derived value multiple times is acceptable.
Implementations§
Source§impl<T> ClockOrdered<T>where
T: Serialize + DeserializeOwned,
impl<T> ClockOrdered<T>where
T: Serialize + DeserializeOwned,
Sourcepub fn new(data: Generic<T>) -> Self
pub fn new(data: Generic<T>) -> Self
Creates a new ClockOrdered. The value is loaded from redis directly.
Sourcepub fn store(&mut self, val: T) -> Result<(), ClockOrderedError>
pub fn store(&mut self, val: T) -> Result<(), ClockOrderedError>
Stores the value in the redis server. The value is only stored if the ordering_number is greater than the current number. The order is incremented by one before each store.
§Example
use dtypes::redis::types::Generic;
use dtypes::redis::sync::ClockOrdered;
let client = redis::Client::open("redis://localhost:6379").unwrap();
let mut i32 = Generic::with_value(1, "test_add_clock_ordered_example1", client.clone());
let mut clock_ordered = ClockOrdered::new(i32);
clock_ordered.store(2).unwrap();
assert_eq!(*clock_ordered, 2);The store can fail if the order is not greater than the current order. This happens, if the value was set from another instance before.
§Example
use std::thread;
use dtypes::redis::types::Generic;
use dtypes::redis::sync::ClockOrdered;
let client = redis::Client::open("redis://localhost:6379").unwrap();
let client2 = client.clone();
thread::scope(|s| {
let t1 = s.spawn(|| {
let mut i32: Generic<i32> = Generic::new("test_add_clock_ordered_example2", client2);
let mut clock_ordered = ClockOrdered::new(i32);
while let Err(_) = clock_ordered.store(2) {}
assert_eq!(*clock_ordered, 2);
});
let mut i32: Generic<i32> = Generic::new("test_add_clock_ordered_example2", client);
let mut clock_ordered = ClockOrdered::new(i32);
while let Err(_) = clock_ordered.store(3) {}
assert_eq!(*clock_ordered, 3);
t1.join().unwrap();
});Sourcepub fn store_blocking(&mut self, val: T) -> Result<(), ClockOrderedError>
pub fn store_blocking(&mut self, val: T) -> Result<(), ClockOrderedError>
Stores the value in the redis server and blocks until succeeds. Everything else is equal to ClockOrdered::store.
§Example
use std::thread;
use dtypes::redis::types::Generic;
use dtypes::redis::sync::ClockOrdered;
let client = redis::Client::open("redis://localhost:6379").unwrap();
let client2 = client.clone();
thread::scope(|s| {
let t1 = s.spawn(|| {
let mut i32: Generic<i32> = Generic::new("test_add_clock_ordered_example3", client2);
let mut clock_ordered = ClockOrdered::new(i32);
clock_ordered.store_blocking(2).unwrap();
assert_eq!(*clock_ordered, 2);
});
let mut i32: Generic<i32> = Generic::new("test_add_clock_ordered_example3", client);
let mut clock_ordered = ClockOrdered::new(i32);
clock_ordered.store_blocking(3).unwrap();
assert_eq!(*clock_ordered, 3);
t1.join().unwrap();
});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}