mithril_common/digesters/
immutable_file_observer.rs1use crate::digesters::ImmutableFile;
2use crate::entities::ImmutableFileNumber;
3use crate::{StdError, StdResult};
4use anyhow::{anyhow, Context};
5use async_trait::async_trait;
6use std::ops::Add;
7use std::path::PathBuf;
8use thiserror::Error;
9use tokio::sync::RwLock;
10
11#[async_trait]
13pub trait ImmutableFileObserver
14where
15 Self: Sync + Send,
16{
17 async fn get_last_immutable_number(&self) -> StdResult<u64>;
19}
20
21#[derive(Error, Debug)]
23pub enum ImmutableFileObserverError {
24 #[error("no immutable file was returned")]
26 Missing(),
27
28 #[error("immutable file creation error")]
30 ImmutableFileListing(#[source] StdError),
31}
32
33pub struct ImmutableFileSystemObserver {
35 db_path: PathBuf,
36}
37
38impl ImmutableFileSystemObserver {
39 pub fn new(db_path: &PathBuf) -> Self {
41 let db_path = db_path.to_owned();
42
43 Self { db_path }
44 }
45}
46
47#[async_trait]
48impl ImmutableFileObserver for ImmutableFileSystemObserver {
49 async fn get_last_immutable_number(&self) -> StdResult<u64> {
50 let immutable_file_number = ImmutableFile::list_completed_in_dir(&self.db_path)
51 .map_err(|e| anyhow!(e))
52 .with_context(|| "Immutable File System Observer can not list all immutable files")?
53 .into_iter()
54 .next_back()
55 .ok_or(anyhow!(ImmutableFileObserverError::Missing()))?
56 .number;
57
58 Ok(immutable_file_number)
59 }
60}
61
62pub struct DumbImmutableFileObserver {
64 pub shall_return: RwLock<Option<ImmutableFileNumber>>,
67}
68
69impl Default for DumbImmutableFileObserver {
70 fn default() -> Self {
71 let mut observer = Self::new();
72 observer.shall_return = RwLock::new(Some(500));
73
74 observer
75 }
76}
77
78impl DumbImmutableFileObserver {
79 pub fn new() -> Self {
81 Self {
82 shall_return: RwLock::new(None),
83 }
84 }
85
86 pub async fn shall_return(&self, what: Option<u64>) -> &Self {
88 let mut shall_return = self.shall_return.write().await;
89 *shall_return = what;
90 self
91 }
92
93 pub async fn increase(&self) -> StdResult<u64> {
96 let new_number = self
97 .shall_return
98 .write()
99 .await
100 .ok_or_else(|| anyhow!(ImmutableFileObserverError::Missing()))?
101 .add(1);
102 self.shall_return(Some(new_number)).await;
103
104 Ok(new_number)
105 }
106}
107
108#[async_trait]
109impl ImmutableFileObserver for DumbImmutableFileObserver {
110 async fn get_last_immutable_number(&self) -> StdResult<u64> {
111 self.shall_return
112 .read()
113 .await
114 .ok_or_else(|| anyhow!(ImmutableFileObserverError::Missing()))
115 }
116}
117
118#[cfg(test)]
119mod tests {}