use super::{RunContext, Runner};
use crate::node_catalog::NodeCatalog;
use crate::executor::RunMode;
use somatize_compiler::ExecutionPlan;
use somatize_core::error::Result;
use somatize_core::value::Value;
use std::collections::HashMap;
pub trait Transport: Send + Sync {
fn execute(
&self,
plan: &ExecutionPlan,
filters: &NodeCatalog,
input: &Value,
mode: &RunMode,
seed: Option<i64>,
) -> Result<(Value, HashMap<String, Value>)>;
fn get_state(&self, node_ids: &[String]) -> Result<HashMap<String, Value>>;
fn set_state(&self, states: &HashMap<String, Value>) -> Result<()>;
fn get_gradients(&self, node_ids: &[String]) -> Result<HashMap<String, Value>>;
fn apply_gradients(&self, gradients: &HashMap<String, Value>) -> Result<()>;
fn execute_node(&self, node_id: &str, input: Option<&Value>) -> Result<Value> {
let plan = ExecutionPlan::Execute {
node_id: node_id.to_string(),
};
let input_val = input.cloned().unwrap_or(Value::Empty);
let filters = crate::node_catalog::NodeCatalog::new();
let (output, _) = self.execute(&plan, &filters, &input_val, &RunMode::Forward, None)?;
Ok(output)
}
}
pub struct RemoteRunner {
transport: Box<dyn Transport>,
}
impl RemoteRunner {
pub fn new(transport: impl Transport + 'static) -> Self {
Self {
transport: Box::new(transport),
}
}
pub fn transport(&self) -> &dyn Transport {
self.transport.as_ref()
}
}
impl Runner for RemoteRunner {
fn fit(
&self,
plan: &ExecutionPlan,
ctx: &RunContext<'_>,
input: &Value,
y: Option<&Value>,
) -> Result<(Value, HashMap<String, Value>)> {
self.transport.execute(
plan,
ctx.catalog,
input,
&RunMode::Fit { y: y.cloned() },
ctx.seed,
)
}
fn forward(&self, plan: &ExecutionPlan, ctx: &RunContext<'_>, input: &Value) -> Result<Value> {
let (output, _states) =
self.transport
.execute(plan, ctx.catalog, input, &RunMode::Forward, ctx.seed)?;
Ok(output)
}
}