Skip to main content

snix_castore/chunkstore/
mod.rs

1#![deny(missing_docs)]
2//! [Chunk] storage.
3
4use auto_impl::auto_impl;
5use tonic::async_trait;
6
7pub mod combinators;
8pub mod grpc;
9pub mod memory;
10pub mod object_store;
11
12use crate::{
13    B3Digest,
14    composition::{Registry, ServiceBuilder},
15};
16
17mod chunk;
18pub use chunk::Chunk;
19
20/// The chunk with zero bytes of payload.
21pub const EMPTY_CHUNK: Chunk = Chunk::from_static(&[]);
22
23/// Allows reading (or uploading) content-addressed chunks of raw data.
24///
25/// BLAKE3 is used as a hashing function for the data. Uploading a blob will
26/// return the BLAKE3 digest of it, and that's the identifier used to Read/Stat
27/// them too.
28///
29/// Chunks are considered small enough to not require any further chunking.
30#[cfg_attr(test, mockall::automock)]
31#[async_trait]
32#[auto_impl(&, &mut, Arc, Box)]
33pub trait ChunkStore: Send + Sync {
34    /// Retrieves a [Chunk] by its [B3Digest], if it exists.
35    async fn get(&self, digest: &B3Digest) -> Result<Option<Chunk>, Error>;
36    /// Check if a Chunk with this [B3Digest] exists.
37    async fn has(&self, digest: &B3Digest) -> Result<bool, Error>;
38    /// Upload a Chunk, returns its [B3Digest].
39    async fn put(&self, chunk: Chunk) -> Result<B3Digest, Error>;
40}
41
42/// Registers the builtin [ChunkStore] implementations with the given [Registry].
43pub(crate) fn register_chunk_stores(reg: &mut Registry) {
44    reg.register::<Box<dyn ServiceBuilder<Output = dyn ChunkStore>>, combinators::CacheConfig>(
45        "cache",
46    );
47    reg.register::<Box<dyn ServiceBuilder<Output = dyn ChunkStore>>, grpc::GRPCChunkStoreConfig>(
48        "grpc",
49    );
50    reg.register::<Box<dyn ServiceBuilder<Output = dyn ChunkStore>>, memory::MemoryChunkStoreConfig>(
51        "memory",
52    );
53    reg.register::<
54        Box<dyn ServiceBuilder<Output = dyn ChunkStore>>,
55        object_store::ObjectStoreChunkStoreConfig,
56    >("objectstore");
57    reg.register::<Box<dyn ServiceBuilder<Output = dyn ChunkStore>>, combinators::PriorityConfig>(
58        "priority",
59    );
60    reg.register::<Box<dyn ServiceBuilder<Output = dyn ChunkStore>>, combinators::RaceConfig>(
61        "race",
62    );
63}
64
65/// Error returned from all ChunkStores.
66///
67/// Usually boxes an inner, more backend-specific error.
68#[derive(thiserror::Error, Debug)]
69#[error(transparent)]
70pub struct Error(Box<dyn std::error::Error + Send + Sync + 'static>);