use crate::retry::OperationRetryer;
use mssf_core::{
ErrorCode,
client::{
FabricClient,
svc_mgmt_client::{PartitionKeyType, ResolvedServicePartition, ServiceManagementClient},
},
runtime::executor::BoxedCancelToken,
types::Uri,
};
use std::time::Duration;
pub struct ServicePartitionResolver {
sm: ServiceManagementClient,
retryer: OperationRetryer,
}
impl ServicePartitionResolver {
pub fn new(fc: FabricClient, retryer: OperationRetryer) -> Self {
ServicePartitionResolver {
sm: fc.get_service_manager().clone(),
retryer,
}
}
#[cfg_attr(
feature = "tracing",
tracing::instrument(skip_all, fields(uri = %name, timeout = ?timeout), err)
)]
pub async fn resolve(
&self,
name: &Uri,
key_type: &PartitionKeyType,
prev: Option<&ResolvedServicePartition>,
timeout: Option<Duration>, token: Option<BoxedCancelToken>,
) -> mssf_core::Result<ResolvedServicePartition> {
self.retryer
.run(
async |t, tk| {
let rsp = self
.sm
.resolve_service_partition(name, key_type, prev, t, tk)
.await?;
if !rsp.endpoints.is_empty() {
Ok(rsp)
} else {
Err(ErrorCode::FABRIC_E_SERVICE_OFFLINE.into())
}
},
timeout,
token,
)
.await
}
}