use std::path::Path;
use std::sync::Arc;
use boatramp_core::kv::{KvStore, MemoryKv};
use crate::error::Result;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
pub enum BlobBackend {
Fs,
S3,
Gcs,
Azure,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
pub enum KvBackend {
Slatedb,
Memory,
Cloudflare,
}
pub const CONTROL_PLANE_FLUSH: std::time::Duration = std::time::Duration::from_millis(5);
#[derive(Debug, Clone)]
pub struct SlateKvS3 {
pub bucket: String,
pub endpoint: Option<String>,
pub region: Option<String>,
pub path_style: bool,
pub prefix: String,
}
pub async fn build_kv(
kv: KvBackend,
data_dir: &Path,
slate_s3: Option<&SlateKvS3>,
) -> Result<Arc<dyn KvStore>> {
match kv {
KvBackend::Slatedb => build_slatedb_kv(data_dir, slate_s3).await,
KvBackend::Memory => Ok(Arc::new(MemoryKv::new())),
KvBackend::Cloudflare => build_cloudflare_kv(),
}
}
#[cfg(feature = "slatedb")]
async fn build_slatedb_kv(
data_dir: &Path,
slate_s3: Option<&SlateKvS3>,
) -> Result<Arc<dyn KvStore>> {
match slate_s3 {
Some(s3) => Ok(Arc::new(
boatramp_storage::SlateKv::open_s3_with_flush(
&boatramp_storage::S3StoreConfig {
bucket: s3.bucket.clone(),
endpoint: s3.endpoint.clone(),
region: s3.region.clone(),
path_style: s3.path_style,
},
&s3.prefix,
CONTROL_PLANE_FLUSH,
)
.await?,
)),
None => Ok(Arc::new(
boatramp_storage::SlateKv::open_local_with_flush(
data_dir.join("kv-slate"),
CONTROL_PLANE_FLUSH,
)
.await?,
)),
}
}
#[cfg(not(feature = "slatedb"))]
async fn build_slatedb_kv(
_data_dir: &Path,
_slate_s3: Option<&SlateKvS3>,
) -> Result<Arc<dyn KvStore>> {
Err(crate::error::Error::NoSlatedbSupport)
}
#[cfg(feature = "cloudflare-kv")]
fn build_cloudflare_kv() -> Result<Arc<dyn KvStore>> {
Ok(Arc::new(boatramp_storage::CloudflareKv::from_env()?))
}
#[cfg(not(feature = "cloudflare-kv"))]
fn build_cloudflare_kv() -> Result<Arc<dyn KvStore>> {
Err(crate::error::Error::NoCloudflareKvSupport)
}