pub mod coordinator;
pub mod map;
pub mod orchestrator;
pub mod reduce;
pub mod setup;
use crate::cook::orchestrator::ExecutionEnvironment;
use crate::cook::workflow::variables::VariableStore;
use crate::subprocess::SubprocessManager;
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
use std::sync::Arc;
pub use coordinator::{PhaseCoordinator, PhaseTransition};
pub use map::MapPhaseExecutor;
pub use orchestrator::{
calculate_optimal_parallelism, plan_phases, should_skip_phase, validate_phase_config,
ExecutionPlan, PhaseSpec, ResourceEstimate,
};
pub use reduce::ReducePhaseExecutor;
pub use setup::SetupPhaseExecutor;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum PhaseType {
Setup,
Map,
Reduce,
}
impl std::fmt::Display for PhaseType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PhaseType::Setup => write!(f, "Setup"),
PhaseType::Map => write!(f, "Map"),
PhaseType::Reduce => write!(f, "Reduce"),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PhaseResult {
pub phase_type: PhaseType,
pub success: bool,
pub data: Option<Value>,
pub error_message: Option<String>,
pub metrics: PhaseMetrics,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct PhaseMetrics {
pub duration_secs: f64,
pub items_processed: usize,
pub items_successful: usize,
pub items_failed: usize,
}
#[derive(Debug, Clone)]
pub struct PhaseContext {
pub variables: HashMap<String, String>,
pub variable_store: Arc<VariableStore>,
pub map_results: Option<Vec<crate::cook::execution::mapreduce::AgentResult>>,
pub checkpoint: Option<PhaseCheckpoint>,
pub environment: ExecutionEnvironment,
pub subprocess_manager: Arc<SubprocessManager>,
}
impl PhaseContext {
pub fn new(
environment: ExecutionEnvironment,
subprocess_manager: Arc<SubprocessManager>,
) -> Self {
Self {
variables: HashMap::new(),
variable_store: Arc::new(VariableStore::new()),
map_results: None,
checkpoint: None,
environment,
subprocess_manager,
}
}
pub fn update_variables(&mut self, variables: HashMap<String, String>) {
self.variables.extend(variables);
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PhaseCheckpoint {
pub phase_type: PhaseType,
pub progress: PhaseProgress,
pub state: Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum PhaseProgress {
NotStarted,
InProgress { step: usize, total: usize },
Completed,
}
#[derive(Debug, thiserror::Error)]
pub enum PhaseError {
#[error("Phase execution failed: {message}")]
ExecutionFailed { message: String },
#[error("Phase transition error: {message}")]
TransitionError { message: String },
#[error("Phase validation failed: {message}")]
ValidationError { message: String },
#[error("Phase timeout: {message}")]
Timeout { message: String },
#[error("MapReduce error: {0}")]
MapReduceError(#[from] crate::cook::execution::errors::MapReduceError),
}
#[async_trait]
pub trait PhaseExecutor: Send + Sync {
async fn execute(&self, context: &mut PhaseContext) -> Result<PhaseResult, PhaseError>;
fn phase_type(&self) -> PhaseType;
fn can_skip(&self, _context: &PhaseContext) -> bool {
false
}
fn validate_context(&self, _context: &PhaseContext) -> Result<(), PhaseError> {
Ok(())
}
}
pub trait PhaseTransitionHandler: Send + Sync {
fn should_execute(&self, phase: PhaseType, context: &PhaseContext) -> bool;
fn on_phase_complete(&self, phase: PhaseType, result: &PhaseResult);
fn on_phase_error(&self, phase: PhaseType, error: &PhaseError) -> PhaseTransition;
}
pub struct DefaultTransitionHandler;
impl PhaseTransitionHandler for DefaultTransitionHandler {
fn should_execute(&self, _phase: PhaseType, _context: &PhaseContext) -> bool {
true
}
fn on_phase_complete(&self, phase: PhaseType, result: &PhaseResult) {
tracing::info!(
"Phase {} completed successfully with {} items processed",
phase,
result.metrics.items_processed
);
}
fn on_phase_error(&self, phase: PhaseType, error: &PhaseError) -> PhaseTransition {
tracing::error!("Phase {} failed: {}", phase, error);
PhaseTransition::Error(format!("{}", error))
}
}
#[cfg(test)]
mod coordinator_test;
#[cfg(test)]
mod map_test;
#[cfg(test)]
mod reduce_test;
#[cfg(test)]
mod setup_test;