tvix_castore/
utils.rs
use std::collections::HashMap;
use std::sync::Arc;
use url::Url;
use crate::blobservice::BlobService;
use crate::composition::{
with_registry, Composition, DeserializeWithRegistry, ServiceBuilder, REG,
};
use crate::directoryservice::DirectoryService;
#[derive(serde::Deserialize, Default)]
pub struct CompositionConfigs {
pub blobservices:
HashMap<String, DeserializeWithRegistry<Box<dyn ServiceBuilder<Output = dyn BlobService>>>>,
pub directoryservices: HashMap<
String,
DeserializeWithRegistry<Box<dyn ServiceBuilder<Output = dyn DirectoryService>>>,
>,
}
#[derive(clap::Parser, Clone)]
#[group(id = "CastoreServiceUrls")]
pub struct ServiceUrls {
#[arg(
long,
env,
default_value = "objectstore+file:///var/lib/tvix-store/blobs.object_store"
)]
pub blob_service_addr: String,
#[arg(
long,
env,
default_value = "redb:///var/lib/tvix-store/directories.redb"
)]
pub directory_service_addr: String,
#[cfg(feature = "xp-composition-cli")]
#[arg(long, env)]
experimental_store_composition: Option<String>,
}
#[derive(clap::Parser, Clone)]
#[group(id = "CastoreServiceUrlsGrpc")]
pub struct ServiceUrlsGrpc {
#[arg(long, env, default_value = "grpc+http://[::1]:8000")]
blob_service_addr: String,
#[arg(long, env, default_value = "grpc+http://[::1]:8000")]
directory_service_addr: String,
#[cfg(feature = "xp-composition-cli")]
#[arg(long, env)]
experimental_store_composition: Option<String>,
}
#[derive(clap::Parser, Clone)]
#[group(id = "CastoreServiceUrlsMemory")]
pub struct ServiceUrlsMemory {
#[arg(long, env, default_value = "memory://")]
blob_service_addr: String,
#[arg(long, env, default_value = "memory://")]
directory_service_addr: String,
#[cfg(feature = "xp-composition-cli")]
#[arg(long, env)]
experimental_store_composition: Option<String>,
}
impl From<ServiceUrlsGrpc> for ServiceUrls {
fn from(urls: ServiceUrlsGrpc) -> ServiceUrls {
ServiceUrls {
blob_service_addr: urls.blob_service_addr,
directory_service_addr: urls.directory_service_addr,
#[cfg(feature = "xp-composition-cli")]
experimental_store_composition: urls.experimental_store_composition,
}
}
}
impl From<ServiceUrlsMemory> for ServiceUrls {
fn from(urls: ServiceUrlsMemory) -> ServiceUrls {
ServiceUrls {
blob_service_addr: urls.blob_service_addr,
directory_service_addr: urls.directory_service_addr,
#[cfg(feature = "xp-composition-cli")]
experimental_store_composition: urls.experimental_store_composition,
}
}
}
pub async fn addrs_to_configs(
urls: impl Into<ServiceUrls>,
) -> Result<CompositionConfigs, Box<dyn std::error::Error + Send + Sync>> {
let urls: ServiceUrls = urls.into();
#[cfg(feature = "xp-composition-cli")]
if let Some(conf_path) = urls.experimental_store_composition {
let conf_text = tokio::fs::read_to_string(conf_path).await?;
return Ok(with_registry(®, || toml::from_str(&conf_text))?);
}
let mut configs: CompositionConfigs = Default::default();
let blob_service_url = Url::parse(&urls.blob_service_addr)?;
let directory_service_url = Url::parse(&urls.directory_service_addr)?;
configs.blobservices.insert(
"root".into(),
with_registry(®, || blob_service_url.try_into())?,
);
configs.directoryservices.insert(
"root".into(),
with_registry(®, || directory_service_url.try_into())?,
);
Ok(configs)
}
pub async fn construct_services(
urls: impl Into<ServiceUrls>,
) -> Result<
(Arc<dyn BlobService>, Arc<dyn DirectoryService>),
Box<dyn std::error::Error + Send + Sync>,
> {
let configs = addrs_to_configs(urls).await?;
construct_services_from_configs(configs).await
}
pub async fn construct_services_from_configs(
configs: CompositionConfigs,
) -> Result<
(Arc<dyn BlobService>, Arc<dyn DirectoryService>),
Box<dyn std::error::Error + Send + Sync>,
> {
let mut comp = Composition::new(®);
comp.extend(configs.blobservices);
comp.extend(configs.directoryservices);
let blob_service: Arc<dyn BlobService> = comp.build("root").await?;
let directory_service: Arc<dyn DirectoryService> = comp.build("root").await?;
Ok((blob_service, directory_service))
}