use crate::id::types::ChildId;
use crate::role::context::sidecar::SidecarContext;
use crate::role::result::sidecar::SidecarError;
use crate::role::traits::sidecar::SidecarRole;
use crate::task::context::TaskContext;
use crate::task::factory::{BoxTaskFuture, Service, TaskResult};
use std::sync::Arc;
use tokio::sync::Mutex;
pub struct SidecarRoleAdapter<T> {
role: Arc<Mutex<T>>,
primary_child_id: ChildId,
}
impl<T> SidecarRoleAdapter<T>
where
T: SidecarRole,
{
pub fn new(role: T, primary_child_id: ChildId) -> Self {
Self {
role: Arc::new(Mutex::new(role)),
primary_child_id,
}
}
}
impl<T> Service for SidecarRoleAdapter<T>
where
T: SidecarRole,
{
fn call(&self, ctx: TaskContext) -> BoxTaskFuture {
let role = self.role.clone();
let primary_child_id = self.primary_child_id.clone();
let sidecar_context = SidecarContext::new(ctx, primary_child_id);
Box::pin(async move {
let mut role = role.lock().await;
run_sidecar_lifecycle(&mut *role, &sidecar_context).await
})
}
}
async fn run_sidecar_lifecycle<T>(role: &mut T, ctx: &SidecarContext) -> TaskResult
where
T: SidecarRole,
{
if let Err(error) = role.init(ctx).await {
return sidecar_error_to_task_result(error);
}
if let Err(error) = role.run(ctx).await {
return sidecar_error_to_task_result(error);
}
if let Err(error) = role.shutdown(ctx).await {
return sidecar_error_to_task_result(error);
}
if ctx.is_shutdown_requested() {
TaskResult::Cancelled
} else {
TaskResult::Succeeded
}
}
fn sidecar_error_to_task_result(error: SidecarError) -> TaskResult {
TaskResult::Failed(error.into_task_failure())
}