escher-execution-engine

Crates.ioescher-execution-engine
lib.rsescher-execution-engine
version0.1.2
created_at2025-12-17 10:55:18.461363+00
updated_at2025-12-17 10:55:18.461363+00
descriptionProduction-ready async execution engine for system commands
homepagehttps://github.com/escher-dbai/v2-execution-engine-rust
repositoryhttps://github.com/escher-dbai/v2-execution-engine-rust
max_upload_size
id1989965
size526,694
Adamya Singh (adamyatessell)

documentation

README

Cloudops Execution Engine

Repository: v2-execution-engine-rust Language: Rust Status: Implementation Phase

Production-ready async execution engine for system commands.

📦 PLAYBOOK INTEGRATION (v2.0.0): This execution engine executes individual commands and doesn't parse playbook files directly. Playbook orchestration (multi-step execution, parameter injection, etc.) is handled by the Execution Manager (TypeScript layer). As of v2.0.0, playbooks use a single-file structure (playbook.json). See v2-architecture-docs for playbook structure details.


Features

  • Async/Non-blocking: Built on Tokio, returns immediately
  • Real-time Streaming: Line-by-line output streaming
  • Concurrency Control: Semaphore-based limiting (default: 100 concurrent)
  • Memory Management: Automatic cleanup system (configurable retention)
  • Resource Limits: Timeout, output size, concurrency limits
  • Event-Driven: Pluggable event handlers for real-time updates

Quick Start

Singleton Initialization (Required)

The engine enforces a Singleton Pattern with Serial Execution (max concurrency = 1) to ensure stability.

use execution_engine::*;

#[tokio::main]
async fn main() {
    // 1. Initialize Global Singleton (Run once at startup)
    let config = ExecutionConfig::default();
    ExecutionEngine::init_global(config).expect("Failed to init engine");

    // 2. Access Global Instance
    let engine = ExecutionEngine::global();

    // 3. Start cleanup task (optional, runs in background)
    // engine.start_cleanup_task(); // Note: Method signature might need Arc wrapping if used directly, 
                                    // but global instance manages state internally.

    // 4. Execute command
    let request = ExecutionRequest {
        id: Uuid::new_v4(),
        command: Command::Shell {
            command: "echo 'Hello World'".to_string(),
            shell: "/bin/bash".to_string(),
        },
        timeout_ms: Some(5000),
        env: HashMap::new(),
        working_dir: None,
        output_log_path: None,
        metadata: Default::default(),
    };

    let execution_id = engine.execute(request).await.unwrap();

    // 5. Get result (non-blocking wait)
    let result = engine.wait_for_completion(execution_id).await.unwrap();

    println!("Success: {}", result.success);
    println!("Output: {}", result.stdout);
}

UI Team Integration

👉 Please read docs/UI-INTEGRATION-GUIDE.md for detailed handoff instructions.

We have provided a TypeScript Bridge for testing:

cd v2-execution-engine-rust
npx ts-node examples/node-caller.ts

Installation

From GitHub (Recommended)

Add this to your Cargo.toml:

[dependencies]
escher-execution-engine = { git = "https://github.com/escher-dbai/v2-execution-engine-rust" }

Installation Options

Latest from main branch:

escher-execution-engine = { git = "https://github.com/escher-dbai/v2-execution-engine-rust", branch = "main" }

Specific version tag:

escher-execution-engine = { git = "https://github.com/escher-dbai/v2-execution-engine-rust", tag = "v0.1.0" }

Specific commit:

escher-execution-engine = { git = "https://github.com/escher-dbai/v2-execution-engine-rust", rev = "abc123" }

With optional features:

escher-execution-engine = {
    git = "https://github.com/escher-dbai/v2-execution-engine-rust",
    tag = "v0.1.0",
    features = ["server-feedback"]
}

Local Development

For local development, use path dependency:

[dependencies]
escher-execution-engine = { path = "../v2-execution-engine-rust" }

Project Structure

v2-execution-engine-rust/
├── src/
│   ├── lib.rs              # Public API exports
│   ├── engine.rs           # ExecutionEngine (main entry point)
│   ├── executor.rs         # Command execution logic
│   ├── config.rs           # ExecutionConfig
│   ├── types.rs            # Request/Result types
│   ├── events.rs           # Event system
│   ├── errors.rs           # Error types
│   ├── commands.rs         # Command builder
│   ├── cleanup.rs          # Memory cleanup system
│   └── tests/              # Unit tests
│
├── tests/                  # Integration tests
│   ├── integration_tests.rs
│   ├── concurrency_tests.rs
│   ├── cleanup_tests.rs
│   └── output_limiting_tests.rs
│
├── examples/               # Usage examples
│   └── standalone.rs
│
├── benches/                # Performance benchmarks
│   └── execution_benchmarks.rs
│
└── docs/                   # Reference documentation
    ├── architecture.md
    ├── api.md
    ├── types.md
    ├── configuration.md
    └── error-handling.md

Documentation

📚 Complete documentation available in docs/

Quick Links

For Developers

External Documentation

Full architecture docs from v2-architecture-docs repository:


Development

Build & Test

# Build
cargo build

# Run tests
cargo test

# Run tests with output
cargo test -- --nocapture

# Run specific test
cargo test test_basic_execution

# Run integration tests only
cargo test --test integration_tests

Examples

# Run standalone example
cargo run --example standalone

Benchmarks

# Run all benchmarks
cargo bench

# Run specific benchmark
cargo bench execution_overhead

Code Quality

# Format code
cargo fmt

# Check formatting
cargo fmt --check

# Run linter
cargo clippy -- -D warnings

# Check for unused dependencies
cargo +nightly udeps

Implementation Status

  • Phase 1: Project Setup & Core Types (1-2 hours)
  • Phase 2: Command Executor (2-3 hours)
  • Phase 3: ExecutionEngine Core (2-3 hours)
  • Phase 4: Operational Features (3-4 hours)
  • Phase 5: Testing & Documentation (2-3 hours)

See IMPLEMENTATION-GUIDE.md for detailed phase breakdown.


Usage in Tauri App

Once implemented, integrate with Tauri:

// src-tauri/src/main.rs

use execution_engine::{ExecutionEngine, ExecutionConfig};
use std::sync::Arc;

#[tokio::main]
async fn main() {
    // Create engine
    let config = ExecutionConfig::default();
    let engine = Arc::new(ExecutionEngine::new(config));

    // Start cleanup
    engine.start_cleanup_task();

    // Share with Tauri
    tauri::Builder::default()
        .manage(engine)
        .invoke_handler(tauri::generate_handler![
            execute_command,
            get_execution_status,
            get_execution_result,
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

#[tauri::command]
async fn execute_command(
    request: ExecutionRequest,
    engine: State<'_, Arc<ExecutionEngine>>,
) -> Result<String, String> {
    let execution_id = engine.execute(request).await
        .map_err(|e| e.to_string())?;

    Ok(execution_id.to_string())
}

Performance Targets

  • Execution overhead: <50ms per command
  • Concurrent throughput: 100+ concurrent executions
  • Memory usage: Bounded by config (default: ~100MB for 1000 executions)
  • Cleanup performance: <1s for 1000 executions

License

Private and Confidential

This software is proprietary and confidential. Unauthorized copying, distribution, or use of this software, via any medium, is strictly prohibited.


Contributing

  1. Read IMPLEMENTATION-GUIDE.md
  2. Create feature branch
  3. Implement with tests
  4. Run cargo test and cargo clippy
  5. Submit PR

Support

For questions or issues:

Commit count: 0

cargo fmt