feat: simplify OpenRPC API and reorganize examples
- Simplified RunnerConfig to just name, command, and optional env - Removed RunnerType and ProcessManagerType enums - Removed db_path, redis_url, binary_path from config - Made runner name also serve as queue name (no separate queue param) - Added secret-based authentication to all runner management methods - Created comprehensive osiris_openrpc example - Archived old examples to _archive/ - Updated client API to match simplified supervisor interface
This commit is contained in:
69
src/app.rs
69
src/app.rs
@@ -5,9 +5,12 @@
|
||||
//! then pass it to SupervisorApp for runtime management.
|
||||
|
||||
use crate::Supervisor;
|
||||
#[cfg(feature = "mycelium")]
|
||||
use crate::mycelium::MyceliumIntegration;
|
||||
use log::{info, error, debug};
|
||||
#[cfg(feature = "mycelium")]
|
||||
use std::sync::Arc;
|
||||
#[cfg(feature = "mycelium")]
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
/// Main supervisor application
|
||||
@@ -54,37 +57,45 @@ impl SupervisorApp {
|
||||
|
||||
/// Start the Mycelium integration
|
||||
async fn start_mycelium_integration(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Skip Mycelium if URL is empty
|
||||
if self.mycelium_url.is_empty() {
|
||||
info!("Mycelium integration disabled (no URL provided)");
|
||||
return Ok(());
|
||||
#[cfg(feature = "mycelium")]
|
||||
{
|
||||
// Skip Mycelium if URL is empty
|
||||
if self.mycelium_url.is_empty() {
|
||||
info!("Mycelium integration disabled (no URL provided)");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
info!("Starting Mycelium integration...");
|
||||
|
||||
let supervisor_for_mycelium = Arc::new(Mutex::new(self.supervisor.clone()));
|
||||
let mycelium_url = self.mycelium_url.clone();
|
||||
let topic = self.topic.clone();
|
||||
|
||||
let mycelium_integration = MyceliumIntegration::new(
|
||||
supervisor_for_mycelium,
|
||||
mycelium_url,
|
||||
topic,
|
||||
);
|
||||
|
||||
// Start the Mycelium integration in a background task
|
||||
let integration_handle = tokio::spawn(async move {
|
||||
if let Err(e) = mycelium_integration.start().await {
|
||||
error!("Mycelium integration error: {}", e);
|
||||
}
|
||||
});
|
||||
|
||||
// Give the integration a moment to start
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
||||
info!("Mycelium integration started successfully");
|
||||
|
||||
// Store the handle for potential cleanup
|
||||
std::mem::forget(integration_handle); // For now, let it run in background
|
||||
}
|
||||
|
||||
info!("Starting Mycelium integration...");
|
||||
|
||||
let supervisor_for_mycelium = Arc::new(Mutex::new(self.supervisor.clone()));
|
||||
let mycelium_url = self.mycelium_url.clone();
|
||||
let topic = self.topic.clone();
|
||||
|
||||
let mycelium_integration = MyceliumIntegration::new(
|
||||
supervisor_for_mycelium,
|
||||
mycelium_url,
|
||||
topic,
|
||||
);
|
||||
|
||||
// Start the Mycelium integration in a background task
|
||||
let integration_handle = tokio::spawn(async move {
|
||||
if let Err(e) = mycelium_integration.start().await {
|
||||
error!("Mycelium integration error: {}", e);
|
||||
}
|
||||
});
|
||||
|
||||
// Give the integration a moment to start
|
||||
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
|
||||
info!("Mycelium integration started successfully");
|
||||
|
||||
// Store the handle for potential cleanup
|
||||
std::mem::forget(integration_handle); // For now, let it run in background
|
||||
#[cfg(not(feature = "mycelium"))]
|
||||
{
|
||||
info!("Mycelium integration not enabled (compile with --features mycelium)");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ pub mod job;
|
||||
pub mod supervisor;
|
||||
pub mod app;
|
||||
pub mod openrpc;
|
||||
|
||||
#[cfg(feature = "mycelium")]
|
||||
pub mod mycelium;
|
||||
|
||||
// Re-export main types for convenience
|
||||
@@ -15,4 +17,6 @@ pub use runner::{Runner, RunnerConfig, RunnerResult, RunnerStatus};
|
||||
pub use supervisor::{Supervisor, SupervisorBuilder, ProcessManagerType};
|
||||
pub use runner_rust::{Job, JobBuilder, JobStatus, JobError, Client, ClientBuilder};
|
||||
pub use app::SupervisorApp;
|
||||
|
||||
#[cfg(feature = "mycelium")]
|
||||
pub use mycelium::{MyceliumIntegration, MyceliumServer};
|
||||
|
||||
@@ -303,20 +303,88 @@ impl MyceliumIntegration {
|
||||
}
|
||||
|
||||
"job.run" => {
|
||||
// Run job and wait for result (blocking)
|
||||
if let Some(param_obj) = params.as_array().and_then(|arr| arr.get(0)) {
|
||||
let _secret = param_obj.get("secret")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or("missing secret")?;
|
||||
let _job = param_obj.get("job")
|
||||
|
||||
let job_value = param_obj.get("job")
|
||||
.ok_or("missing job")?;
|
||||
|
||||
// TODO: Implement actual job execution
|
||||
Ok(json!("job_queued"))
|
||||
let timeout = param_obj.get("timeout")
|
||||
.and_then(|v| v.as_u64())
|
||||
.unwrap_or(60);
|
||||
|
||||
// Deserialize the job
|
||||
let job: runner_rust::job::Job = serde_json::from_value(job_value.clone())
|
||||
.map_err(|e| format!("invalid job format: {}", e))?;
|
||||
|
||||
let job_id = job.id.clone();
|
||||
let runner_name = job.runner.clone();
|
||||
|
||||
// Verify signatures
|
||||
job.verify_signatures()
|
||||
.map_err(|e| format!("signature verification failed: {}", e))?;
|
||||
|
||||
info!("Job {} signature verification passed for signatories: {:?}",
|
||||
job_id, job.signatories());
|
||||
|
||||
// Queue and wait for result
|
||||
let mut supervisor_guard = self.supervisor.lock().await;
|
||||
let result = supervisor_guard.queue_and_wait(&runner_name, job, timeout)
|
||||
.await
|
||||
.map_err(|e| format!("job execution failed: {}", e))?;
|
||||
|
||||
Ok(json!({
|
||||
"job_id": job_id,
|
||||
"status": "completed",
|
||||
"result": result
|
||||
}))
|
||||
} else {
|
||||
Err("invalid job.run params".into())
|
||||
}
|
||||
}
|
||||
|
||||
"job.start" => {
|
||||
// Start job without waiting (non-blocking)
|
||||
if let Some(param_obj) = params.as_array().and_then(|arr| arr.get(0)) {
|
||||
let _secret = param_obj.get("secret")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or("missing secret")?;
|
||||
|
||||
let job_value = param_obj.get("job")
|
||||
.ok_or("missing job")?;
|
||||
|
||||
// Deserialize the job
|
||||
let job: runner_rust::job::Job = serde_json::from_value(job_value.clone())
|
||||
.map_err(|e| format!("invalid job format: {}", e))?;
|
||||
|
||||
let job_id = job.id.clone();
|
||||
let runner_name = job.runner.clone();
|
||||
|
||||
// Verify signatures
|
||||
job.verify_signatures()
|
||||
.map_err(|e| format!("signature verification failed: {}", e))?;
|
||||
|
||||
info!("Job {} signature verification passed for signatories: {:?}",
|
||||
job_id, job.signatories());
|
||||
|
||||
// Queue the job without waiting
|
||||
let mut supervisor_guard = self.supervisor.lock().await;
|
||||
supervisor_guard.queue_job_to_runner(&runner_name, job)
|
||||
.await
|
||||
.map_err(|e| format!("failed to queue job: {}", e))?;
|
||||
|
||||
Ok(json!({
|
||||
"job_id": job_id,
|
||||
"status": "queued"
|
||||
}))
|
||||
} else {
|
||||
Err("invalid job.start params".into())
|
||||
}
|
||||
}
|
||||
|
||||
"job.status" => {
|
||||
if let Some(_job_id) = params.as_array().and_then(|arr| arr.get(0)).and_then(|v| v.as_str()) {
|
||||
// TODO: Implement actual job status lookup
|
||||
@@ -339,7 +407,7 @@ impl MyceliumIntegration {
|
||||
let methods = vec![
|
||||
"list_runners", "register_runner", "start_runner", "stop_runner",
|
||||
"get_runner_status", "get_all_runner_status", "start_all", "stop_all",
|
||||
"job.run", "job.status", "job.result", "rpc.discover"
|
||||
"job.run", "job.start", "job.status", "job.result", "rpc.discover"
|
||||
];
|
||||
Ok(json!(methods))
|
||||
}
|
||||
|
||||
@@ -330,7 +330,6 @@ pub trait SupervisorRpc {
|
||||
#[method(name = "queue_job_to_runner")]
|
||||
async fn queue_job_to_runner(&self, params: QueueJobParams) -> RpcResult<()>;
|
||||
|
||||
|
||||
/// Get a job by job ID
|
||||
#[method(name = "get_job")]
|
||||
async fn get_job(&self, job_id: String) -> RpcResult<Job>;
|
||||
|
||||
Reference in New Issue
Block a user