forked from herocode/horus
supervisor cleanup, documentation and minor fixes
This commit is contained in:
110
bin/supervisor/src/main.rs
Normal file
110
bin/supervisor/src/main.rs
Normal file
@@ -0,0 +1,110 @@
|
||||
//! Hero Supervisor Binary
|
||||
|
||||
use hero_supervisor::SupervisorBuilder;
|
||||
use clap::Parser;
|
||||
use log::{error, info};
|
||||
|
||||
/// Hero Supervisor - manages actors and dispatches jobs
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(name = "supervisor")]
|
||||
#[command(about = "Hero Supervisor - manages actors and dispatches jobs")]
|
||||
struct Args {
|
||||
/// Redis URL for job queue
|
||||
#[arg(long, default_value = "redis://127.0.0.1:6379")]
|
||||
redis_url: String,
|
||||
|
||||
/// Namespace for Redis keys
|
||||
#[arg(long, default_value = "")]
|
||||
namespace: String,
|
||||
|
||||
/// Admin secrets (required, can be specified multiple times)
|
||||
#[arg(long = "admin-secret", value_name = "SECRET", required = true)]
|
||||
admin_secrets: Vec<String>,
|
||||
|
||||
/// User secrets (can be specified multiple times)
|
||||
#[arg(long = "user-secret", value_name = "SECRET")]
|
||||
user_secrets: Vec<String>,
|
||||
|
||||
/// Register secrets (can be specified multiple times)
|
||||
#[arg(long = "register-secret", value_name = "SECRET")]
|
||||
register_secrets: Vec<String>,
|
||||
|
||||
/// Port for OpenRPC HTTP server
|
||||
#[arg(long, default_value = "3030")]
|
||||
port: u16,
|
||||
|
||||
/// Bind address for OpenRPC HTTP server
|
||||
#[arg(long, default_value = "127.0.0.1")]
|
||||
bind_address: String,
|
||||
|
||||
/// Pre-configured runner names (comma-separated)
|
||||
#[arg(long, value_name = "NAMES", value_delimiter = ',')]
|
||||
runners: Vec<String>,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
env_logger::init();
|
||||
let args = Args::parse();
|
||||
|
||||
// Build supervisor
|
||||
let mut builder = SupervisorBuilder::new()
|
||||
.admin_secrets(args.admin_secrets);
|
||||
|
||||
if !args.user_secrets.is_empty() {
|
||||
builder = builder.user_secrets(args.user_secrets);
|
||||
}
|
||||
|
||||
if !args.register_secrets.is_empty() {
|
||||
builder = builder.register_secrets(args.register_secrets);
|
||||
}
|
||||
|
||||
let mut supervisor = builder.build().await?;
|
||||
|
||||
// Register pre-configured runners
|
||||
if !args.runners.is_empty() {
|
||||
for runner_name in &args.runners {
|
||||
match supervisor.runner_create(runner_name.clone()).await {
|
||||
Ok(_) => {},
|
||||
Err(e) => error!("Failed to register runner '{}': {}", runner_name, e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start OpenRPC server
|
||||
use hero_supervisor::openrpc::start_http_openrpc_server;
|
||||
|
||||
let supervisor_clone = supervisor.clone();
|
||||
let bind_addr = args.bind_address.clone();
|
||||
let port = args.port;
|
||||
|
||||
tokio::spawn(async move {
|
||||
match start_http_openrpc_server(supervisor_clone, &bind_addr, port).await {
|
||||
Ok(handle) => {
|
||||
handle.stopped().await;
|
||||
error!("OpenRPC server stopped unexpectedly");
|
||||
}
|
||||
Err(e) => {
|
||||
error!("OpenRPC server error: {}", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(500)).await;
|
||||
|
||||
// Print startup info
|
||||
println!("📡 http://{}:{}", args.bind_address, args.port);
|
||||
info!("Hero Supervisor is running. Press Ctrl+C to shutdown.");
|
||||
|
||||
// Set up graceful shutdown
|
||||
tokio::spawn(async move {
|
||||
tokio::signal::ctrl_c().await.expect("Failed to listen for ctrl+c");
|
||||
info!("Received shutdown signal");
|
||||
std::process::exit(0);
|
||||
});
|
||||
|
||||
// Keep the application running
|
||||
loop {
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user