Skip to content

Commit 75e17f4

Browse files
committed
fix(meta): metastore availability improvements
- `zstor monitor` not failed when the metastore failed - `zstor store` check metastore.writetable status before storing the data
1 parent 6d8698b commit 75e17f4

File tree

4 files changed

+38
-7
lines changed

4 files changed

+38
-7
lines changed

zstor/src/actors/meta.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ pub struct DeleteFailure {
8282
pub fm: FailureMeta,
8383
}
8484

85+
#[derive(Message)]
86+
#[rtype(result = "bool")]
87+
/// Message to check if the metastore is writable.
88+
pub struct CheckWritable;
89+
8590
#[derive(Message)]
8691
#[rtype(result = "Result<Vec<FailureMeta>, MetaStoreError>")]
8792
/// Message for retrieving all [`FailureMeta`] objects in a [`MetaStore`] managed by a [`MetaStoreActor`].
@@ -111,10 +116,11 @@ pub struct MetaStoreActor {
111116

112117
impl MetaStoreActor {
113118
/// Create a new [`MetaStoreActor`] from a given [`MetaStore`].
114-
pub fn new(meta_store: Box<dyn MetaStore>) -> MetaStoreActor {
119+
pub fn new(meta_store: Box<dyn MetaStore>, writeable: bool) -> MetaStoreActor {
120+
log::info!("metastore actor writeable: {}", writeable);
115121
Self {
116122
meta_store: Arc::from(meta_store),
117-
writeable: true,
123+
writeable: writeable,
118124
}
119125
}
120126
}
@@ -221,6 +227,15 @@ impl Handler<SaveFailure> for MetaStoreActor {
221227
}
222228
}
223229

230+
impl Handler<CheckWritable> for MetaStoreActor {
231+
type Result = ResponseFuture<bool>;
232+
233+
fn handle(&mut self, _: CheckWritable, _: &mut Self::Context) -> Self::Result {
234+
let writeable = self.writeable;
235+
Box::pin(async move { writeable })
236+
}
237+
}
238+
224239
impl Handler<DeleteFailure> for MetaStoreActor {
225240
type Result = ResponseFuture<Result<(), MetaStoreError>>;
226241

zstor/src/actors/zstor.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::actors::{
22
config::{ConfigActor, GetConfig},
3-
meta::{LoadMeta, LoadMetaByKey, MetaStoreActor, SaveMeta, SaveMetaByKey},
3+
meta::{CheckWritable, LoadMeta, LoadMetaByKey, MetaStoreActor, SaveMeta, SaveMetaByKey},
44
metrics::{MetricsActor, ZstorCommandFinsihed, ZstorCommandId},
55
pipeline::{PipelineActor, RebuildData, RecoverFile, StoreFile},
66
};
@@ -138,8 +138,17 @@ impl Handler<Store> for ZstorActor {
138138
let pipeline = self.pipeline.clone();
139139
let config = self.cfg.clone();
140140
let meta = self.meta.clone();
141+
141142
AtomicResponse::new(Box::pin(
142143
async move {
144+
let meta_writeable = meta.send(CheckWritable).await.unwrap();
145+
if !meta_writeable {
146+
return Err(ZstorError::new_io(
147+
"Metastore is not writable".to_string(),
148+
std::io::Error::from(std::io::ErrorKind::PermissionDenied),
149+
));
150+
}
151+
143152
let ft = fs::metadata(&msg.file)
144153
.await
145154
.map_err(|e| ZstorError::new_io("Could not load file metadata".into(), e))?

zstor/src/lib.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use compression::CompressorError;
2424
use config::ConfigError;
2525
use encryption::EncryptionError;
2626
use erasure::EncodingError;
27-
use futures::future::try_join_all;
27+
use futures::future::join_all;
2828
use meta::MetaStoreError;
2929
use std::fmt;
3030
use std::path::{Path, PathBuf};
@@ -63,17 +63,18 @@ pub type ZstorResult<T> = Result<T, ZstorError>;
6363
pub async fn setup_system(cfg_path: PathBuf, cfg: &Config) -> ZstorResult<Addr<ZstorActor>> {
6464
let metastore = match cfg.meta() {
6565
Meta::Zdb(zdb_cfg) => {
66-
let backends = try_join_all(
66+
let backends = join_all(
6767
zdb_cfg
6868
.backends()
6969
.iter()
7070
.map(|ci| UserKeyZdb::new(ci.clone())),
7171
)
72-
.await?;
72+
.await;
7373
let encryptor = match cfg.encryption() {
7474
Encryption::Aes(key) => encryption::AesGcm::new(key.clone()),
7575
};
7676
let encoder = zdb_cfg.encoder();
77+
let backends = backends.into_iter().filter_map(|res| res.ok()).collect();
7778
Box::new(ZdbMetaStore::new(
7879
backends,
7980
encoder,
@@ -88,7 +89,8 @@ pub async fn setup_system(cfg_path: PathBuf, cfg: &Config) -> ZstorResult<Addr<Z
8889
if let Some(mountpoint) = cfg.zdbfs_mountpoint() {
8990
let _ = ZdbFsStatsProxyActor::new(mountpoint.to_path_buf(), metrics_addr.clone()).start();
9091
}
91-
let meta_addr = MetaStoreActor::new(metastore).start();
92+
let meta_writable = metastore.writable();
93+
let meta_addr = MetaStoreActor::new(metastore, meta_writable).start();
9294
let cfg_addr = ConfigActor::new(cfg_path, cfg.clone()).start();
9395
let pipeline_addr = SyncArbiter::start(1, || PipelineActor);
9496

zstor/src/zdb_meta.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ where
114114
}
115115
}
116116

117+
/// writable returns true if the metastore is writable
118+
pub fn writable(&self) -> bool {
119+
self.writeable
120+
}
121+
117122
/// helper functions to encrypt and write data to backends.
118123
async fn write_value(&self, key: &str, value: &[u8]) -> ZdbMetaStoreResult<()> {
119124
debug!("Writing data to zdb metastore");

0 commit comments

Comments
 (0)