This shouldn't be part of the PathInfoService trait. Pretty much none of the PathInfoServices do implement it, and requiring them to implement it means they also cannot make use of this calculation already being done by other PathInfoServices. Move it out into its own NarCalculationService trait, defined somewhere at tvix_store::nar, and have everyone who wants to trigger nar calculation use nar_calculation_service directly, which now is an additional field in TvixStoreIO for example. It being moved outside the PathInfoService trait doesn't prohibit specific implementations to implement it (like the GRPC client for the `PathInfoService` does. This is currently wired together in a bit of a hacky fashion - as of now, everything uses the naive implementation that traverses blob and directoryservice, rather than composing it properly. I want to leave that up to a later CL, dealing with other parts of store composition too. Change-Id: I18d07ea4301d4a07651b8218bc5fe95e4e307208 Reviewed-on: https://cl.tvl.fyi/c/depot/+/11619 Reviewed-by: Connor Brewster <cbrewster@hey.com> Autosubmit: flokli <flokli@flokli.de> Tested-by: BuildkiteCI
78 lines
2.2 KiB
Rust
78 lines
2.2 KiB
Rust
use std::sync::Arc;
|
|
use std::{
|
|
pin::Pin,
|
|
task::{self, Poll},
|
|
};
|
|
use tokio::io::{self, AsyncWrite};
|
|
|
|
use tvix_castore::{
|
|
blobservice::{self, BlobService},
|
|
directoryservice::{self, DirectoryService},
|
|
};
|
|
|
|
use crate::nar::{NarCalculationService, SimpleRenderer};
|
|
use crate::pathinfoservice::{self, PathInfoService};
|
|
|
|
/// Construct the store handles from their addrs.
|
|
pub async fn construct_services(
|
|
blob_service_addr: impl AsRef<str>,
|
|
directory_service_addr: impl AsRef<str>,
|
|
path_info_service_addr: impl AsRef<str>,
|
|
) -> std::io::Result<(
|
|
Arc<dyn BlobService>,
|
|
Arc<dyn DirectoryService>,
|
|
Box<dyn PathInfoService>,
|
|
Box<dyn NarCalculationService>,
|
|
)> {
|
|
let blob_service: Arc<dyn BlobService> = blobservice::from_addr(blob_service_addr.as_ref())
|
|
.await?
|
|
.into();
|
|
let directory_service: Arc<dyn DirectoryService> =
|
|
directoryservice::from_addr(directory_service_addr.as_ref())
|
|
.await?
|
|
.into();
|
|
let path_info_service = pathinfoservice::from_addr(
|
|
path_info_service_addr.as_ref(),
|
|
blob_service.clone(),
|
|
directory_service.clone(),
|
|
)
|
|
.await?;
|
|
|
|
// TODO: grpc client also implements NarCalculationService
|
|
let nar_calculation_service = Box::new(SimpleRenderer::new(
|
|
blob_service.clone(),
|
|
directory_service.clone(),
|
|
)) as Box<dyn NarCalculationService>;
|
|
|
|
Ok((
|
|
blob_service,
|
|
directory_service,
|
|
path_info_service,
|
|
nar_calculation_service,
|
|
))
|
|
}
|
|
|
|
/// The inverse of [tokio_util::io::SyncIoBridge].
|
|
/// Don't use this with anything that actually does blocking I/O.
|
|
pub struct AsyncIoBridge<T>(pub T);
|
|
|
|
impl<W: std::io::Write + Unpin> AsyncWrite for AsyncIoBridge<W> {
|
|
fn poll_write(
|
|
self: Pin<&mut Self>,
|
|
_cx: &mut task::Context<'_>,
|
|
buf: &[u8],
|
|
) -> Poll<io::Result<usize>> {
|
|
Poll::Ready(self.get_mut().0.write(buf))
|
|
}
|
|
|
|
fn poll_flush(self: Pin<&mut Self>, _cx: &mut task::Context<'_>) -> Poll<io::Result<()>> {
|
|
Poll::Ready(self.get_mut().0.flush())
|
|
}
|
|
|
|
fn poll_shutdown(
|
|
self: Pin<&mut Self>,
|
|
_cx: &mut task::Context<'_>,
|
|
) -> Poll<Result<(), io::Error>> {
|
|
Poll::Ready(Ok(()))
|
|
}
|
|
}
|