Skip to main content

kmp_application/queries/
query_application_service.rs

1use std::sync::Arc;
2
3#[derive(Debug)]
4pub struct QueryApplicationService<G, D, S> {
5    pub(crate) graph_reader: Arc<G>,
6    pub(crate) detail_reader: Arc<D>,
7    pub(crate) snapshot_store: Arc<S>,
8    pub(crate) generator_version: &'static str,
9    read_snapshot_provider: Option<Arc<dyn kmp_domain::ReadSnapshotProvider<G, D>>>,
10}
11
12impl<G, D, S> QueryApplicationService<G, D, S> {
13    pub fn new(
14        graph_reader: Arc<G>,
15        detail_reader: Arc<D>,
16        snapshot_store: Arc<S>,
17        generator_version: &'static str,
18    ) -> Self {
19        Self {
20            graph_reader,
21            detail_reader,
22            snapshot_store,
23            generator_version,
24            read_snapshot_provider: None,
25        }
26    }
27    /// Configure a backend that owns graph and bodies in one store. Without
28    /// this provider separate adapters retain their best-effort read semantics.
29    /// A configured provider error propagates; it never falls back to live reads.
30    pub fn with_read_snapshots(
31        mut self,
32        provider: Arc<dyn kmp_domain::ReadSnapshotProvider<G, D>>,
33    ) -> Self {
34        self.read_snapshot_provider = Some(provider);
35        self
36    }
37
38    pub async fn read_snapshot(&self) -> Result<Option<Self>, crate::ApplicationError> {
39        let Some(provider) = &self.read_snapshot_provider else {
40            return Ok(None);
41        };
42        let (graph, detail) = provider.open_snapshot().await?;
43        Ok(Some(Self::new(
44            Arc::new(graph),
45            Arc::new(detail),
46            Arc::clone(&self.snapshot_store),
47            self.generator_version,
48        )))
49    }
50}
51
52impl<G: kmp_domain::GraphNeighborhoodReader + Send + Sync, D, S> QueryApplicationService<G, D, S> {
53    pub(crate) async fn graph_read_revision(
54        &self,
55    ) -> Result<Option<kmp_domain::GraphReadRevision>, crate::ApplicationError> {
56        Ok(self.graph_reader.graph_read_revision().await?)
57    }
58
59    pub async fn read_nodes(
60        &self,
61        request: &kmp_domain::MemoryNodesRequest,
62    ) -> Result<kmp_domain::MemoryNodesResult, crate::ApplicationError> {
63        Ok(self.graph_reader.load_memory_nodes(request).await?)
64    }
65
66    pub async fn evidence_paths(
67        &self,
68        request: &kmp_domain::EvidencePathRequest,
69    ) -> Result<kmp_domain::EvidencePathResult, crate::ApplicationError> {
70        request
71            .validate()
72            .map_err(|e| crate::ApplicationError::Validation(e.to_string()))?;
73        Ok(self.graph_reader.load_evidence_paths(request).await?)
74    }
75
76    pub async fn trace_search(
77        &self,
78        request: &kmp_domain::TraceSearchRequest,
79    ) -> Result<kmp_domain::TraceSearchResult, crate::ApplicationError> {
80        Ok(self.graph_reader.load_bounded_trace(request).await?)
81    }
82}