snix_castore/directoryservice/
simple_putter.rs1use super::Directory;
2use super::DirectoryPutter;
3use super::DirectoryService;
4use crate::B3Digest;
5use crate::directoryservice::directory_graph::DirectoryGraphBuilder;
6use tonic::async_trait;
7use tracing::instrument;
8use tracing::warn;
9
10pub struct SimplePutter<'a, DS> {
14 directory_service: &'a DS,
15
16 builder: Option<DirectoryGraphBuilder>,
17}
18
19impl<'a, DS> SimplePutter<'a, DS>
20where
21 DS: DirectoryService,
22{
23 pub fn new(directory_service: &'a DS) -> Self {
24 Self {
25 directory_service,
26 builder: Some(DirectoryGraphBuilder::new_leaves_to_root()),
27 }
28 }
29}
30
31#[async_trait]
32impl<DS: DirectoryService + 'static> DirectoryPutter for SimplePutter<'_, DS> {
33 #[instrument(level = "trace", skip_all, fields(directory.digest=%directory.digest()), err)]
34 async fn put(&mut self, directory: Directory) -> Result<(), super::Error> {
35 let builder = self.builder.as_mut().ok_or_else(|| Error::AlreadyClosed)?;
36
37 builder.try_insert(directory)?;
38
39 Ok(())
40 }
41
42 #[instrument(level = "trace", skip_all, ret, err)]
43 async fn close(&mut self) -> Result<B3Digest, super::Error> {
44 let builder = self.builder.take().ok_or_else(|| Error::AlreadyClosed)?;
45
46 let directory_graph = builder.build()?;
48 let root_digest = directory_graph.root().digest();
49
50 for directory in directory_graph.drain_leaves_to_root() {
51 let exp_digest = directory.digest();
52 let actual_digest = self.directory_service.put(directory).await?;
53
54 if exp_digest != actual_digest {
56 warn!(directory.digest_expected=%exp_digest, directory.digest_actual=%actual_digest, "unexpected digest");
57 Err(Error::UnexpectedDigest {
58 expected: exp_digest,
59 actual: actual_digest,
60 })?;
61 }
62 }
63
64 Ok(root_digest)
65 }
66}
67
68#[derive(thiserror::Error, Debug)]
69pub enum Error {
70 #[error("DirectoryGraphBuilder already closed")]
71 AlreadyClosed,
72 #[error("got unexpected digest from backend, expected {expected}, actual {actual}")]
73 UnexpectedDigest {
74 expected: B3Digest,
75 actual: B3Digest,
76 },
77 #[error("failure during graph validation")]
78 GraphValidation(#[from] super::OrderingError),
79}