omry_integration/
bridge.rs1use anyhow::Result;
3use omry_service::archiving::{Record, RecordParams};
4use omry_service::common::RecordId;
5use omry_service::search::SearchResponse;
6use omry_service::search_wrappers::SearchParametersWrapper;
7use omry_service::service::RecordIds;
8use omry_service::tarpc::context;
9use omry_service::{FloraServiceClient, PONG};
10use std::sync::Arc;
11use tokio::task::JoinSet;
12use tracing::instrument;
13
14#[allow(async_fn_in_trait)]
17pub trait ServiceBridge {
18 fn client(&self) -> &FloraServiceClient;
20
21 #[instrument(skip(self))]
25 async fn ping(&self) -> Result<String> {
26 let response = self.client().ping(context::current()).await?;
27 if response == PONG {
28 Ok(response)
29 } else {
30 anyhow::bail!("Unexpected ping response: {response}")
31 }
32 }
33
34 #[instrument(skip(self))]
36 async fn add_record(&self, record: RecordParams) -> Result<RecordId> {
37 let id = self
38 .client()
39 .add_record(context::current(), record)
40 .await?
41 .map_err(|e| anyhow::anyhow!("{e}"))?;
42 Ok(id)
43 }
44
45 #[instrument(skip(self))]
47 async fn count(&self) -> Result<i64> {
48 let count = self
49 .client()
50 .count(context::current())
51 .await?
52 .map_err(|e| anyhow::anyhow!("{e}"))?;
53 Ok(count)
54 }
55
56 #[instrument(skip(self))]
58 async fn get_records(&self, record_ids: RecordIds) -> Result<Arc<Vec<Record>>> {
59 let records = self
60 .client()
61 .get_records(context::current(), record_ids)
62 .await?
63 .map_err(|e| anyhow::anyhow!("{e}"))?;
64 Ok(records)
65 }
66
67 #[instrument(skip(self))]
69 async fn search(&self, search_parameters: SearchParametersWrapper) -> Result<SearchResponse> {
70 let search_result = self
71 .client()
72 .search(context::current(), search_parameters)
73 .await?
74 .map_err(|e| anyhow::anyhow!("{e}"))?;
75
76 Ok(search_result)
77 }
78
79 #[instrument(skip(self))]
82 async fn delete(&self, ids: Vec<RecordId>) -> Result<usize> {
83 tracing::debug!(
84 "Will make {} RPCs to delete the given IDs (one per each)",
85 ids.len()
86 );
87
88 let mut set = JoinSet::new();
89 for id in ids {
90 let client = self.client().clone();
91
92 set.spawn(async move {
93 client
94 .delete_record(context::current(), id)
95 .await
96 .map_err(|error| error.to_string())
97 .flatten()
98 });
99 }
100
101 let mut n_deleted = 0usize;
102 let mut n_errors = 0usize;
103 let results = set.join_all().await;
104 for result in results {
105 match result {
106 Ok(n) => n_deleted += n,
107 Err(error) => {
108 tracing::error!("Error calling `delete_record`: {error}");
109 n_errors += 1;
110 }
111 }
112 }
113
114 if n_errors != 0 {
115 anyhow::bail!("{n_errors} records couldn't be scheduled for deletion due to errors.");
116 }
117
118 Ok(n_deleted)
119 }
120}