use anyhow::Result;
use omry_service::archiving::{Record, RecordParams};
use omry_service::common::RecordId;
use omry_service::search::SearchResponse;
use omry_service::search_wrappers::SearchParametersWrapper;
use omry_service::service::RecordIds;
use omry_service::tarpc::context;
use omry_service::{FloraServiceClient, PONG};
use std::sync::Arc;
use tokio::task::JoinSet;
use tracing::instrument;
#[allow(async_fn_in_trait)]
pub trait ServiceBridge {
fn client(&self) -> &FloraServiceClient;
#[instrument(skip(self))]
async fn ping(&self) -> Result<String> {
let response = self.client().ping(context::current()).await?;
if response == PONG {
Ok(response)
} else {
anyhow::bail!("Unexpected ping response: {response}")
}
}
#[instrument(skip(self))]
async fn add_record(&self, record: RecordParams) -> Result<RecordId> {
let id = self
.client()
.add_record(context::current(), record)
.await?
.map_err(|e| anyhow::anyhow!("{e}"))?;
Ok(id)
}
#[instrument(skip(self))]
async fn count(&self) -> Result<i64> {
let count = self
.client()
.count(context::current())
.await?
.map_err(|e| anyhow::anyhow!("{e}"))?;
Ok(count)
}
#[instrument(skip(self))]
async fn get_records(&self, record_ids: RecordIds) -> Result<Arc<Vec<Record>>> {
let records = self
.client()
.get_records(context::current(), record_ids)
.await?
.map_err(|e| anyhow::anyhow!("{e}"))?;
Ok(records)
}
#[instrument(skip(self))]
async fn search(&self, search_parameters: SearchParametersWrapper) -> Result<SearchResponse> {
let search_result = self
.client()
.search(context::current(), search_parameters)
.await?
.map_err(|e| anyhow::anyhow!("{e}"))?;
Ok(search_result)
}
#[instrument(skip(self))]
async fn delete(&self, ids: Vec<RecordId>) -> Result<usize> {
tracing::debug!(
"Will make {} RPCs to delete the given IDs (one per each)",
ids.len()
);
let mut set = JoinSet::new();
for id in ids {
let client = self.client().clone();
set.spawn(async move {
client
.delete_record(context::current(), id)
.await
.map_err(|error| error.to_string())
.flatten()
});
}
let mut n_deleted = 0usize;
let mut n_errors = 0usize;
let results = set.join_all().await;
for result in results {
match result {
Ok(n) => n_deleted += n,
Err(error) => {
tracing::error!("Error calling `delete_record`: {error}");
n_errors += 1;
}
}
}
if n_errors != 0 {
anyhow::bail!("{n_errors} records couldn't be scheduled for deletion due to errors.");
}
Ok(n_deleted)
}
}