.. | ||
cmd | ||
docs | ||
examples | ||
src | ||
.gitignore | ||
Cargo.toml | ||
README.md |
Hero Dispatcher
A Redis-based job dispatcher for managing Rhai/HeroScript execution across distributed workers.
Overview
The Hero Dispatcher provides a robust job queue system where:
- Jobs represent script execution requests (Rhai or HeroScript)
- Creating a job stores job parameters in Redis as an hset entry
- Submitting a job pushes the job ID to a worker's queue
- Running a job creates, submits, and awaits results on a dedicated reply queue
Key Features
- Asynchronous Operations: Built with
tokio
for non-blocking I/O - Request-Reply Pattern: Submit jobs and await results without polling
- Configurable Jobs: Set timeouts, retries, concurrency, and logging options
- Worker Targeting: Direct job routing to specific worker queues
- Job Lifecycle: Create, submit, monitor status, and retrieve results
Core Components
DispatcherBuilder
Builder for creating Dispatcher
instances with caller ID, worker ID, context ID, and Redis URL.
Dispatcher
Main interface for job management:
new_job()
- Create a newJobBuilder
create_job()
- Store job in Redisrun_job_and_await_result()
- Execute job and wait for completionget_job_status()
- Check job execution statusget_job_output()
- Retrieve job results
JobBuilder
Fluent builder for configuring jobs:
script()
- Set the script contentworker_id()
- Target specific workertimeout()
- Set execution timeoutbuild()
- Create the jobsubmit()
- Fire-and-forget submissionawait_response()
- Submit and wait for result
Job
Represents a script execution request with:
- Unique ID and timestamps
- Script content and target worker
- Execution settings (timeout, retries, concurrency)
- Logging configuration
Redis Schema
Jobs are stored using the hero:
namespace:
hero:job:{job_id}
- Job parameters as Redis hashhero:work_queue:{worker_id}
- Worker-specific job queueshero:reply:{job_id}
- Dedicated reply queues for results
Prerequisites
- Redis server accessible by dispatcher and workers
Usage Example
Basic Job Creation and Submission
use hero_dispatcher::{DispatcherBuilder, DispatcherError};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create dispatcher
let dispatcher = DispatcherBuilder::new()
.caller_id("my-app")
.worker_id("worker-1")
.context_id("my-context")
.redis_url("redis://127.0.0.1:6379")
.build()?;
// Create a job
let job = dispatcher
.new_job()
.script(r#"print("Hello from worker!"); "success""#)
.timeout(Duration::from_secs(30))
.build()?;
// Store job in Redis
dispatcher.create_job(&job)?;
println!("Job {} created and stored in Redis", job.id);
// Run job and await result (requires worker)
match dispatcher.run_job_and_await_result(&job, "worker-1".to_string()) {
Ok(result) => println!("Job completed: {}", result),
Err(DispatcherError::Timeout(_)) => println!("Job timed out"),
Err(e) => println!("Job failed: {}", e),
}
Ok(())
}
Job Status Monitoring
// Check job status
match dispatcher.get_job_status(&job.id) {
Ok(status) => println!("Job status: {:?}", status),
Err(e) => println!("Error getting status: {}", e),
}
// Get job output
match dispatcher.get_job_output(&job.id) {
Ok(output) => println!("Job output: {:?}", output),
Err(e) => println!("Error getting output: {}", e),
}
Examples
Run the comprehensive demo to see dispatcher functionality and Redis entries:
cargo run --example dispatcher_demo
Other examples:
timeout_example.rs
- Demonstrates timeout handling
Ensure Redis is running at redis://127.0.0.1:6379
.