t_rust_less_lib/block_store/sync/
mod.rs

1use 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    // Note: Intentionally left blank. There should be no nested sync stores
89    Ok(())
90  }
91}