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:
@@ -26,6 +26,7 @@ indexmap = "2.0"
|
||||
jsonrpsee = { version = "0.24", features = ["http-client", "macros"] }
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
hero-supervisor = { path = "../.." }
|
||||
runner_rust = { git = "https://git.ourworld.tf/herocode/runner_rust.git", branch = "main" }
|
||||
env_logger = "0.11"
|
||||
|
||||
# WASM-specific dependencies
|
||||
|
||||
@@ -115,40 +115,16 @@ impl From<wasm_bindgen::JsValue> for ClientError {
|
||||
/// Result type for client operations
|
||||
pub type ClientResult<T> = Result<T, ClientError>;
|
||||
|
||||
/// Types of runners supported by the supervisor
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum RunnerType {
|
||||
/// SAL Runner for system abstraction layer operations
|
||||
SALRunner,
|
||||
/// OSIS Runner for operating system interface operations
|
||||
OSISRunner,
|
||||
/// V Runner for virtualization operations
|
||||
VRunner,
|
||||
/// Python Runner for Python-based actors
|
||||
PyRunner,
|
||||
}
|
||||
|
||||
/// Process manager type for WASM compatibility
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ProcessManagerType {
|
||||
Simple,
|
||||
Tmux(String),
|
||||
}
|
||||
|
||||
/// Configuration for an actor runner
|
||||
/// Configuration for a runner
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct RunnerConfig {
|
||||
/// Unique identifier for the actor
|
||||
pub actor_id: String,
|
||||
/// Type of runner
|
||||
pub runner_type: RunnerType,
|
||||
/// Path to the actor binary
|
||||
pub binary_path: PathBuf,
|
||||
/// Database path for the actor
|
||||
pub db_path: String,
|
||||
/// Redis URL for job queue
|
||||
pub redis_url: String,
|
||||
/// Name of the runner
|
||||
pub name: String,
|
||||
/// Command to run the runner (full command line)
|
||||
pub command: String,
|
||||
/// Optional environment variables
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub env: Option<std::collections::HashMap<String, String>>,
|
||||
}
|
||||
|
||||
|
||||
@@ -171,6 +147,21 @@ pub struct JobStatusResponse {
|
||||
pub completed_at: Option<String>,
|
||||
}
|
||||
|
||||
/// Response from job.run (blocking execution)
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct JobRunResponse {
|
||||
pub job_id: String,
|
||||
pub status: String,
|
||||
pub result: Option<String>,
|
||||
}
|
||||
|
||||
/// Response from job.start (non-blocking execution)
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct JobStartResponse {
|
||||
pub job_id: String,
|
||||
pub status: String,
|
||||
}
|
||||
|
||||
// Re-export Job types from runner_rust crate (native only)
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub use runner_rust::{Job, JobStatus, JobError, JobBuilder, Client, ClientBuilder};
|
||||
@@ -219,7 +210,7 @@ pub type ProcessStatus = ProcessStatusWrapper;
|
||||
|
||||
/// Re-export types from supervisor crate for native builds
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub use hero_supervisor::{ProcessManagerType, RunnerStatus};
|
||||
pub use hero_supervisor::RunnerStatus;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
pub use hero_supervisor::runner::LogInfo;
|
||||
|
||||
@@ -262,17 +253,17 @@ impl SupervisorClient {
|
||||
}
|
||||
|
||||
/// Register a new runner to the supervisor with secret authentication
|
||||
/// The runner name is also used as the queue name
|
||||
pub async fn register_runner(
|
||||
&self,
|
||||
secret: &str,
|
||||
name: &str,
|
||||
queue: &str,
|
||||
) -> ClientResult<()> {
|
||||
let _: () = self
|
||||
.client
|
||||
.request(
|
||||
"register_runner",
|
||||
rpc_params![secret, name, queue],
|
||||
rpc_params![secret, name],
|
||||
)
|
||||
.await.map_err(|e| ClientError::JsonRpc(e))?;
|
||||
Ok(())
|
||||
@@ -305,40 +296,47 @@ impl SupervisorClient {
|
||||
Ok(jobs)
|
||||
}
|
||||
|
||||
/// Run a job on the appropriate runner and return the result
|
||||
/// Run a job on the appropriate runner and wait for the result (blocking)
|
||||
/// This method queues the job and waits for completion before returning
|
||||
pub async fn job_run(
|
||||
&self,
|
||||
secret: &str,
|
||||
job: Job,
|
||||
) -> ClientResult<JobResult> {
|
||||
let params = serde_json::json!({
|
||||
timeout: Option<u64>,
|
||||
) -> ClientResult<JobRunResponse> {
|
||||
let mut params = serde_json::json!({
|
||||
"secret": secret,
|
||||
"job": job
|
||||
});
|
||||
|
||||
let result: JobResult = self
|
||||
if let Some(t) = timeout {
|
||||
params["timeout"] = serde_json::json!(t);
|
||||
}
|
||||
|
||||
let result: JobRunResponse = self
|
||||
.client
|
||||
.request("job.run", rpc_params![params])
|
||||
.await.map_err(|e| ClientError::JsonRpc(e))?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Start a previously created job by queuing it to its assigned runner
|
||||
/// Start a job without waiting for the result (non-blocking)
|
||||
/// This method queues the job and returns immediately with the job_id
|
||||
pub async fn job_start(
|
||||
&self,
|
||||
secret: &str,
|
||||
job_id: &str,
|
||||
) -> ClientResult<()> {
|
||||
job: Job,
|
||||
) -> ClientResult<JobStartResponse> {
|
||||
let params = serde_json::json!({
|
||||
"secret": secret,
|
||||
"job_id": job_id
|
||||
"job": job
|
||||
});
|
||||
|
||||
let _: () = self
|
||||
let result: JobStartResponse = self
|
||||
.client
|
||||
.request("job.start", rpc_params![params])
|
||||
.await.map_err(|e| ClientError::JsonRpc(e))?;
|
||||
Ok(())
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
/// Get the current status of a job
|
||||
@@ -360,10 +358,14 @@ impl SupervisorClient {
|
||||
}
|
||||
|
||||
/// Remove a runner from the supervisor
|
||||
pub async fn remove_runner(&self, actor_id: &str) -> ClientResult<()> {
|
||||
pub async fn remove_runner(&self, secret: &str, actor_id: &str) -> ClientResult<()> {
|
||||
let params = serde_json::json!({
|
||||
"secret": secret,
|
||||
"actor_id": actor_id
|
||||
});
|
||||
let _: () = self
|
||||
.client
|
||||
.request("remove_runner", rpc_params![actor_id])
|
||||
.request("remove_runner", rpc_params![params])
|
||||
.await.map_err(|e| ClientError::JsonRpc(e))?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -378,37 +380,54 @@ impl SupervisorClient {
|
||||
}
|
||||
|
||||
/// Start a specific runner
|
||||
pub async fn start_runner(&self, actor_id: &str) -> ClientResult<()> {
|
||||
pub async fn start_runner(&self, secret: &str, actor_id: &str) -> ClientResult<()> {
|
||||
let params = serde_json::json!({
|
||||
"secret": secret,
|
||||
"actor_id": actor_id
|
||||
});
|
||||
let _: () = self
|
||||
.client
|
||||
.request("start_runner", rpc_params![actor_id])
|
||||
.request("start_runner", rpc_params![params])
|
||||
.await.map_err(|e| ClientError::JsonRpc(e))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Stop a specific runner
|
||||
pub async fn stop_runner(&self, actor_id: &str, force: bool) -> ClientResult<()> {
|
||||
pub async fn stop_runner(&self, secret: &str, actor_id: &str, force: bool) -> ClientResult<()> {
|
||||
let params = serde_json::json!({
|
||||
"secret": secret,
|
||||
"actor_id": actor_id,
|
||||
"force": force
|
||||
});
|
||||
let _: () = self
|
||||
.client
|
||||
.request("stop_runner", rpc_params![actor_id, force])
|
||||
.request("stop_runner", rpc_params![params])
|
||||
.await.map_err(|e| ClientError::JsonRpc(e))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add a runner to the supervisor
|
||||
pub async fn add_runner(&self, config: RunnerConfig, process_manager: ProcessManagerType) -> ClientResult<()> {
|
||||
pub async fn add_runner(&self, secret: &str, config: RunnerConfig) -> ClientResult<()> {
|
||||
let params = serde_json::json!({
|
||||
"secret": secret,
|
||||
"config": config
|
||||
});
|
||||
let _: () = self
|
||||
.client
|
||||
.request("add_runner", rpc_params![config, process_manager])
|
||||
.request("add_runner", rpc_params![params])
|
||||
.await.map_err(|e| ClientError::JsonRpc(e))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get status of a specific runner
|
||||
pub async fn get_runner_status(&self, actor_id: &str) -> ClientResult<RunnerStatus> {
|
||||
pub async fn get_runner_status(&self, secret: &str, actor_id: &str) -> ClientResult<RunnerStatus> {
|
||||
let params = serde_json::json!({
|
||||
"secret": secret,
|
||||
"actor_id": actor_id
|
||||
});
|
||||
let status: RunnerStatus = self
|
||||
.client
|
||||
.request("get_runner_status", rpc_params![actor_id])
|
||||
.request("get_runner_status", rpc_params![params])
|
||||
.await.map_err(|e| ClientError::JsonRpc(e))?;
|
||||
Ok(status)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user