use std::io::Result;
use std::pin::Pin;
use std::future::Future;
use log::debug;
use uuid::Uuid;
use hyperfile::staging::{StagingIntercept, s3::S3Staging};
use hyperfile::inode::FlushInodeFlag;
use crate::{DirStaging, DirScatterInodeOp};
#[derive(Clone)]
pub struct ScatterFirstInterceptor {
parent_dir_staging: S3Staging,
name: String,
uuid: Uuid,
}
impl ScatterFirstInterceptor {
pub fn new(parent_dir_staging: S3Staging, name: impl Into<String>, uuid: Uuid) -> Self {
Self { parent_dir_staging, name: name.into(), uuid }
}
}
impl StagingIntercept<S3Staging> for ScatterFirstInterceptor {
fn before_flush_inode(
&self,
_staging: &S3Staging,
payload: &[u8],
flag: FlushInodeFlag,
) -> Pin<Box<dyn Future<Output = Result<()>> + '_ + Send>> {
let parent = self.parent_dir_staging.clone();
let name = self.name.clone();
let uuid = self.uuid;
let payload = payload.to_vec();
Box::pin(async move {
let op = match flag {
FlushInodeFlag::Create => DirScatterInodeOp::Create,
FlushInodeFlag::Update => DirScatterInodeOp::Update,
FlushInodeFlag::Delete => {
debug!("ScatterFirstInterceptor: skipping FlushInodeFlag::Delete (use fs_unlink instead)");
return Ok(());
},
FlushInodeFlag::Ignore | FlushInodeFlag::Unkown => {
debug!("ScatterFirstInterceptor: skipping flag {:?}", flag);
return Ok(());
},
};
parent.emit_scatter_event(&name, &uuid, &payload, op).await
})
}
fn after_flush_inode(
&self,
_staging: &S3Staging,
_payload: &[u8],
_flag: FlushInodeFlag,
) -> Pin<Box<dyn Future<Output = Result<()>> + '_ + Send>> {
Box::pin(async { Ok(()) })
}
fn after_remove_inode(
&self,
_staging: &S3Staging,
) -> Pin<Box<dyn Future<Output = Result<()>> + '_ + Send>> {
Box::pin(async { Ok(()) })
}
}