t_rust_less_lib/block_store/sync/
mod.rs1use std::sync::{Arc, Mutex};
2
3use crate::memguard::weak::ZeroingWords;
4
5use super::{BlockStore, ChangeLog, RingContent, RingId, StoreError, StoreResult};
6
7mod synchronize;
8
9#[cfg(test)]
10mod synchronize_tests;
11
12#[derive(Debug)]
13pub struct SyncBlockStore {
14 local: Arc<dyn BlockStore>,
15 remote: Arc<dyn BlockStore>,
16 sync_lock: Arc<Mutex<()>>,
17}
18
19impl SyncBlockStore {
20 pub fn new(local: Arc<dyn BlockStore>, remote: Arc<dyn BlockStore>) -> SyncBlockStore {
21 SyncBlockStore {
22 local,
23 remote,
24 sync_lock: Arc::new(Mutex::new(())),
25 }
26 }
27
28 pub fn synchronize(&self) -> StoreResult<bool> {
29 let _guard = self.sync_lock.lock()?;
30
31 let mut local_changes = synchronize::synchronize_rings(self.local.clone(), self.remote.clone())?;
32 local_changes |= synchronize::synchronize_blocks(self.local.clone(), self.remote.clone())?;
33
34 Ok(local_changes)
35 }
36}
37
38impl BlockStore for SyncBlockStore {
39 fn node_id(&self) -> &str {
40 self.local.node_id()
41 }
42
43 fn list_ring_ids(&self) -> StoreResult<Vec<RingId>> {
44 self.local.list_ring_ids()
45 }
46
47 fn get_ring(&self, ring_id: &str) -> StoreResult<RingContent> {
48 match self.local.get_ring(ring_id) {
49 Ok(ring) => Ok(ring),
50 Err(StoreError::InvalidBlock(_)) => self.remote.get_ring(ring_id),
51 Err(err) => Err(err),
52 }
53 }
54
55 fn store_ring(&self, ring_id: &str, version: u64, raw: &[u8]) -> StoreResult<()> {
56 self.local.store_ring(ring_id, version, raw)
57 }
58
59 fn change_logs(&self) -> StoreResult<Vec<super::ChangeLog>> {
60 self.local.change_logs()
61 }
62
63 fn get_index(&self, index_id: &str) -> StoreResult<Option<ZeroingWords>> {
64 self.local.get_index(index_id)
65 }
66
67 fn store_index(&self, index_id: &str, raw: &[u8]) -> StoreResult<()> {
68 self.local.store_index(index_id, raw)
69 }
70
71 fn add_block(&self, raw: &[u8]) -> StoreResult<String> {
72 self.local.add_block(raw)
73 }
74
75 fn get_block(&self, block: &str) -> StoreResult<ZeroingWords> {
76 match self.local.get_block(block) {
77 Ok(content) => Ok(content),
78 Err(StoreError::InvalidBlock(_)) => self.remote.get_block(block),
79 Err(err) => Err(err),
80 }
81 }
82
83 fn commit(&self, changes: &[super::Change]) -> StoreResult<()> {
84 self.local.commit(changes)
85 }
86
87 fn update_change_log(&self, _change_log: ChangeLog) -> StoreResult<()> {
88 Ok(())
90 }
91}