1use async_trait::async_trait;
9use std::{fmt::Display, result::Result as StdResult, sync::Arc};
10
11mod prometheus {
12 include!(concat!(env!("OUT_DIR"), "/prometheus.rs"));
13}
14pub use prometheus::*;
15
16#[derive(Debug)]
17pub enum Error {
18 SnappyEncode(snap::Error),
19 SnappyDecode(snap::Error),
20 ProtoDecode(prost::DecodeError),
21}
22
23pub type Result<T> = StdResult<T, Error>;
24
25impl Display for Error {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 match self {
28 Self::SnappyEncode(_) => f.write_str("SnappyEncode"),
29 Self::SnappyDecode(_) => f.write_str("SnappyDecode"),
30 Self::ProtoDecode(_) => f.write_str("ProtoDecode"),
31 }
32 }
33}
34
35impl std::error::Error for Error {
36 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
37 match self {
38 Self::SnappyEncode(e) => Some(e),
39 Self::SnappyDecode(e) => Some(e),
40 Self::ProtoDecode(e) => Some(e),
41 }
42 }
43}
44
45#[async_trait]
50pub trait RemoteStorage: Sync {
51 type Err: Send;
53
54 type Context: Send + Sync;
56
57 async fn write(&self, ctx: Self::Context, req: WriteRequest) -> StdResult<(), Self::Err>;
59
60 async fn process_query(
65 &self,
66 ctx: &Self::Context,
67 q: Query,
68 ) -> StdResult<QueryResult, Self::Err>;
69
70 async fn read(
74 &self,
75 ctx: Self::Context,
76 req: ReadRequest,
77 ) -> StdResult<ReadResponse, Self::Err> {
78 let results = futures::future::join_all(
79 req.queries
80 .into_iter()
81 .map(|q| async { self.process_query(&ctx, q).await }),
82 )
83 .await
84 .into_iter()
85 .collect::<StdResult<Vec<_>, Self::Err>>()?;
86
87 Ok(ReadResponse { results })
88 }
89}
90
91pub type RemoteStorageRef<C, E> = Arc<dyn RemoteStorage<Err = E, Context = C> + Send + Sync>;