use std::path::PathBuf;
use std::time::SystemTime;
use async_trait::async_trait;
use crate::storage::partition::PartitionGranularity;
use crate::types::{ArchDbType, ArchiverSample, EventStreamDesc};
#[derive(Debug, Clone)]
pub struct StoreSummary {
pub name: String,
pub root_folder: PathBuf,
pub granularity: PartitionGranularity,
pub pv_file_count: Option<u64>,
pub pv_size_bytes: Option<u64>,
pub total_size_bytes: Option<u64>,
pub total_files: Option<u64>,
}
pub trait EventStream: Send {
fn description(&self) -> &EventStreamDesc;
fn next_event(&mut self) -> anyhow::Result<Option<ArchiverSample>>;
}
#[derive(Debug, Clone, Default)]
pub struct AppendMeta {
pub element_count: Option<i32>,
pub headers: Vec<(String, String)>,
}
#[derive(Debug, Clone, Default)]
pub struct IngestFlushResult {
pub failed: Vec<String>,
pub deferred: Vec<String>,
}
#[async_trait]
pub trait StoragePlugin: Send + Sync {
fn name(&self) -> &str;
fn partition_granularity(&self) -> PartitionGranularity;
async fn append_event(
&self,
pv: &str,
dbr_type: ArchDbType,
sample: &ArchiverSample,
) -> anyhow::Result<()>;
async fn append_event_with_meta(
&self,
pv: &str,
dbr_type: ArchDbType,
sample: &ArchiverSample,
_meta: &AppendMeta,
) -> anyhow::Result<()> {
self.append_event(pv, dbr_type, sample).await
}
async fn get_data(
&self,
pv: &str,
start: SystemTime,
end: SystemTime,
) -> anyhow::Result<Vec<Box<dyn EventStream>>>;
async fn get_last_known_event(&self, pv: &str) -> anyhow::Result<Option<ArchiverSample>>;
async fn get_last_event_before(
&self,
pv: &str,
target: SystemTime,
) -> anyhow::Result<Option<ArchiverSample>> {
match self.get_last_known_event(pv).await? {
Some(sample) if sample.timestamp < target => Ok(Some(sample)),
_ => Ok(None),
}
}
async fn delete_pv_data(&self, _pv: &str) -> anyhow::Result<u64> {
Ok(0)
}
async fn flush_writes(&self) -> anyhow::Result<()> {
Ok(())
}
async fn flush_ingest_writes(&self) -> anyhow::Result<IngestFlushResult> {
self.flush_writes()
.await
.map(|_| IngestFlushResult::default())
}
fn stores_for_pv(&self, pv: &str) -> anyhow::Result<Vec<StoreSummary>>;
fn appliance_metrics(&self) -> anyhow::Result<Vec<StoreSummary>>;
async fn rename_pv(&self, _from: &str, _to: &str) -> anyhow::Result<u64> {
anyhow::bail!("rename_pv not implemented for this storage plugin")
}
}
pub trait PostProcessor: Send {
fn name(&self) -> &str;
fn interval_secs(&self) -> u64;
fn process(&self, input: Box<dyn EventStream>) -> Box<dyn EventStream>;
}