use crate::actors::{Handler, Message, OrchestrationActor};
use crate::orchestration::lifecycle::task_request_processor::TaskRequestProcessor;
use async_trait::async_trait;
use std::sync::Arc;
use tasker_shared::messaging::TaskRequestMessage;
use tasker_shared::system_context::SystemContext;
use tasker_shared::{TaskerError, TaskerResult};
use tracing::{debug, info};
use uuid::Uuid;
#[derive(Debug, Clone)]
pub struct ProcessTaskRequestMessage {
pub request: TaskRequestMessage,
}
impl Message for ProcessTaskRequestMessage {
type Response = Uuid;
}
#[derive(Debug)]
pub struct TaskRequestActor {
context: Arc<SystemContext>,
service: Arc<TaskRequestProcessor>,
}
impl TaskRequestActor {
pub fn new(context: Arc<SystemContext>, service: Arc<TaskRequestProcessor>) -> Self {
Self { context, service }
}
}
impl OrchestrationActor for TaskRequestActor {
fn name(&self) -> &'static str {
"TaskRequestActor"
}
fn context(&self) -> &Arc<SystemContext> {
&self.context
}
fn started(&mut self) -> TaskerResult<()> {
info!(
actor = %self.name(),
"TaskRequestActor started - ready to process task requests"
);
Ok(())
}
fn stopped(&mut self) -> TaskerResult<()> {
info!(
actor = %self.name(),
"TaskRequestActor stopped"
);
Ok(())
}
}
#[async_trait]
impl Handler<ProcessTaskRequestMessage> for TaskRequestActor {
type Response = Uuid;
async fn handle(&self, msg: ProcessTaskRequestMessage) -> TaskerResult<Self::Response> {
debug!(
actor = %self.name(),
namespace = %msg.request.task_request.namespace,
name = %msg.request.task_request.name,
"Processing task request message"
);
let payload = serde_json::to_value(&msg.request).map_err(|e| {
TaskerError::ValidationError(format!("Failed to serialize task request: {e}"))
})?;
let task_uuid = self
.service
.process_task_request(&payload)
.await
.map_err(|e| {
TaskerError::OrchestrationError(format!("Task initialization failed: {e}"))
})?;
debug!(
actor = %self.name(),
task_uuid = %task_uuid,
"Task request processed successfully"
);
Ok(task_uuid)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_task_request_actor_implements_traits() {
fn assert_orchestration_actor<T: OrchestrationActor>() {}
fn assert_handler<T: Handler<ProcessTaskRequestMessage>>() {}
assert_orchestration_actor::<TaskRequestActor>();
assert_handler::<TaskRequestActor>();
}
#[test]
fn test_process_task_request_message_implements_message() {
fn assert_message<T: Message>() {}
assert_message::<ProcessTaskRequestMessage>();
}
}