use crate::MuxNode;
use super::{http::execute_node, ExecutionStack, GlueNode, HeapMap};
use std::{
fs,
sync::{Arc, Mutex},
};
#[derive(Debug)]
pub struct Runner {
pub root: MuxNode,
pub layers: ExecutionStack,
pub depth: usize,
pub result: Option<String>,
pub heap: HeapMap,
pub log_info: bool,
}
impl Runner {
fn new(root: MuxNode, heap: HeapMap, log_info: bool) -> Self {
let mut runner = Runner {
root,
layers: vec![vec![]],
depth: 0,
result: None,
heap,
log_info,
};
runner.build_layers();
runner
}
pub fn from_root_node(root: GlueNode, heap: HeapMap, log_info: bool) -> Self {
Runner::new(Arc::new(Mutex::new(root)), heap, log_info)
}
pub fn from_string(command: &String, heap: HeapMap, log_info: bool) -> Result<Self, String> {
match GlueNode::from_string(command) {
Err(x) => Err(x),
Ok(x) => Ok(Runner::from_root_node(x, heap, log_info)),
}
}
pub fn from_file(path: &String, heap: HeapMap, log_info: bool) -> Result<Self, String> {
let command = match fs::read_to_string(path) {
Err(x) => return Err(x.to_string()),
Ok(x) => x,
};
match GlueNode::from_string(&command) {
Err(x) => Err(x),
Ok(x) => Ok(Runner::from_root_node(x, heap, log_info)),
}
}
pub fn add_node(self: &mut Self, node: MuxNode) -> () {
let r_node = node.lock().unwrap();
if self.depth < r_node.depth {
self.add_layer();
}
drop(r_node);
self.layers[self.depth].push(node);
}
pub async fn execute(self: &mut Self) -> Result<(), String> {
for layer in self.layers.iter() {
let mut tasks = vec![];
for request in layer.iter() {
let mut w_request = request.lock().unwrap();
w_request.resolve_dependencies();
tasks.push(execute_node(
Arc::clone(&request),
Arc::clone(&self.heap),
self.log_info,
))
}
for task in tasks {
task.await?;
}
}
self.result = Some(String::from(&self.root.lock().unwrap().result));
Ok(())
}
fn add_layer(self: &mut Self) -> () {
self.layers.push(vec![]);
self.depth += 1;
}
fn add_node_recursive(self: &mut Self, node: MuxNode) -> () {
self.add_node(Arc::clone(&node));
let r_node = node.lock().unwrap();
for dep_node in &r_node.dependencies {
self.add_node_recursive(Arc::clone(dep_node));
}
}
fn build_layers(self: &mut Self) -> () {
self.add_node_recursive(Arc::clone(&self.root));
self.layers.reverse();
}
}