Crate goblin_engine

Crate goblin_engine 

Source
Expand description

§Goblin Engine

A high-performance, async workflow engine for executing scripts in planned sequences.

Goblin Engine allows you to define scripts, create execution plans that orchestrate multiple scripts, handle dependencies between steps automatically, and execute workflows asynchronously with proper error handling.

§Features

  • Async Execution: Fully asynchronous workflow execution using Tokio
  • Dependency Resolution: Automatic topological sorting and cycle detection
  • Type Safety: Compile-time validation with rich error types
  • Concurrent Execution: Execute independent steps concurrently
  • Template Interpolation: Reference previous step outputs in later steps
  • Script Auto-Discovery: Automatically find and load scripts from directories
  • Flexible Configuration: TOML-based configuration with validation

§Quick Start

use goblin_engine::{Engine, EngineConfig};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create and configure engine
    let config = EngineConfig::from_file("goblin.toml")?;
    let engine = Engine::new()
        .with_scripts_dir(config.scripts_dir.unwrap());

    // Auto-discover scripts
    engine.auto_discover_scripts()?;

    // Execute a plan
    let context = engine.execute_plan("my_plan", Some("input".to_string())).await?;

    println!("Execution completed in {:?}", context.elapsed());
    for (step, result) in context.results {
        println!("{}: {}", step, result);
    }

    Ok(())
}

§Core Concepts

§Scripts

A Script represents an executable unit with configuration. Scripts are defined via goblin.toml files in script directories:

name = "example_script"
command = "deno run --allow-all main.ts"
timeout = 500  # seconds
test_command = "deno test"
require_test = false

§Plans

A Plan orchestrates multiple scripts in a defined sequence, with automatic dependency resolution. Plans are defined in TOML files:

name = "example_plan"

[[steps]]
name = "step_one"
function = "script_name"
inputs = ["default_input"]

[[steps]]
name = "step_two"
function = "another_script"
inputs = ["step_one", "literal_value"]  # References step_one's output

§Engine

The Engine is the main orchestrator that loads scripts and plans, resolves dependencies, and executes workflows.

§Module Organization

  • engine: Core engine implementation and execution context
  • script: Script configuration and management
  • plan: Plan definition, step configuration, and dependency resolution
  • executor: Script execution trait and default implementation
  • error: Error types and result aliases
  • config: Engine configuration from TOML files

§Error Handling

All fallible operations return a Result<T> type alias that uses GoblinError as the error type. Errors are structured with rich context for debugging.

use goblin_engine::{GoblinError, Result};

fn example() -> Result<()> {
    // Operations that may fail return Result<T>
    Ok(())
}

Re-exports§

pub use engine::Engine;
pub use engine::EnginePool;
pub use engine::EngineGuard;
pub use engine::PoolStats;
pub use script::Script;
pub use script::ScriptConfig;
pub use plan::Plan;
pub use plan::Step;
pub use plan::StepInput;
pub use error::GoblinError;
pub use error::Result;
pub use executor::Executor;
pub use executor::ExecutionResult;
pub use config::EngineConfig;

Modules§

config
engine
error
executor
plan
script