pub(crate) async fn direct_oneshot(
ctx: &camel_core::CamelContext,
uri: &str,
exchange: camel_api::Exchange,
) -> Result<camel_api::Exchange, camel_api::CamelError> {
use tower::ServiceExt;
const RETRY_SLEEP: std::time::Duration = std::time::Duration::from_millis(20);
const RETRY_DEADLINE: std::time::Duration = std::time::Duration::from_secs(1);
let deadline = tokio::time::Instant::now() + RETRY_DEADLINE;
loop {
let producer_ctx = ctx.producer_context();
let component = ctx
.registry()
.get("direct")
.expect("direct component registered by the bundle cascade"); let endpoint = component
.create_endpoint(uri, ctx)
.expect("direct endpoint creation must succeed"); let producer = endpoint
.create_producer(
std::sync::Arc::new(camel_component_api::NoOpComponentContext),
&producer_ctx,
)
.expect("direct producer creation must succeed"); match producer.oneshot(exchange.clone()).await {
Ok(reply) => return Ok(reply),
Err(e) => {
let is_startup_race = !camel_component_seda::is_no_active_consumers_gate(&e)
&& matches!(e, camel_api::CamelError::EndpointCreationFailed(_));
if is_startup_race && tokio::time::Instant::now() < deadline {
tokio::time::sleep(RETRY_SLEEP).await;
continue;
}
return Err(e);
}
}
}
}