Files
supervisor/clients/admin-ui/src/services.rs
2025-08-27 10:07:53 +02:00

146 lines
5.2 KiB
Rust

use gloo::console;
use std::rc::Rc;
use std::cell::RefCell;
use crate::wasm_client::{WasmSupervisorClient, WasmClientResult as ClientResult, RunnerConfig, ProcessManagerType, ProcessStatus, LogInfo, Job, RunnerType};
use wasm_bindgen_futures::spawn_local;
use yew::prelude::*;
use crate::types::{RunnerInfo, AppState};
/// Service for managing supervisor client operations
#[derive(Clone)]
pub struct SupervisorService {
client: Rc<RefCell<WasmSupervisorClient>>,
}
impl PartialEq for SupervisorService {
fn eq(&self, other: &Self) -> bool {
// Compare by server URL since that's the main identifier
self.client.borrow().server_url() == other.client.borrow().server_url()
}
}
impl SupervisorService {
pub fn new(server_url: &str) -> ClientResult<Self> {
let client = WasmSupervisorClient::new(server_url);
Ok(Self {
client: Rc::new(RefCell::new(client)),
})
}
/// Get all runners with their status and basic info
pub async fn get_all_runners(&self) -> ClientResult<Vec<RunnerInfo>> {
let runner_ids = self.client.borrow_mut().list_runners().await?;
let mut runners = Vec::new();
for id in runner_ids {
let status = self.client.borrow_mut().get_runner_status(&id).await.unwrap_or(ProcessStatus::Unknown);
let logs = self.client.borrow_mut().get_runner_logs(&id, Some(50), false).await.unwrap_or_default();
// Create a basic runner config since we don't have a get_runner_config method
let config = RunnerConfig {
actor_id: id.clone(),
runner_type: RunnerType::SALRunner, // Default
binary_path: std::path::PathBuf::from("unknown"),
script_type: "unknown".to_string(),
args: vec![],
env_vars: std::collections::HashMap::new(),
working_dir: None,
restart_policy: "always".to_string(),
health_check_command: None,
dependencies: vec![],
};
runners.push(RunnerInfo {
id,
config,
status,
logs,
});
}
Ok(runners)
}
/// Add a new runner
pub async fn add_runner(&self, config: RunnerConfig, process_manager_type: ProcessManagerType) -> ClientResult<()> {
self.client.borrow_mut().add_runner(config, process_manager_type).await
}
/// Remove a runner
pub async fn remove_runner(&self, actor_id: &str) -> ClientResult<()> {
self.client.borrow_mut().remove_runner(actor_id).await
}
/// Start a runner
pub async fn start_runner(&self, actor_id: &str) -> ClientResult<()> {
self.client.borrow_mut().start_runner(actor_id).await
}
/// Stop a runner
pub async fn stop_runner(&self, actor_id: &str, force: bool) -> ClientResult<()> {
self.client.borrow_mut().stop_runner(actor_id, force).await
}
/// Get runner status
pub async fn get_runner_status(&self, actor_id: &str) -> ClientResult<ProcessStatus> {
self.client.borrow_mut().get_runner_status(actor_id).await
}
/// Get runner logs
pub async fn get_runner_logs(&self, actor_id: &str, lines: Option<usize>, follow: bool) -> ClientResult<Vec<LogInfo>> {
self.client.borrow_mut().get_runner_logs(actor_id, lines, follow).await
}
/// Start all runners
pub async fn start_all(&self) -> ClientResult<Vec<(String, bool)>> {
self.client.borrow_mut().start_all().await
}
/// Stop all runners
pub async fn stop_all(&self, force: bool) -> ClientResult<Vec<(String, bool)>> {
self.client.borrow_mut().stop_all(force).await
}
/// Queue a job to a runner
pub async fn queue_job(&self, runner: &str, job: Job) -> ClientResult<()> {
self.client.borrow_mut().queue_job_to_runner(runner, job).await
}
/// Queue a job and wait for result
pub async fn queue_and_wait(&self, runner: &str, job: Job, timeout_secs: u64) -> ClientResult<Option<String>> {
self.client.borrow_mut().queue_and_wait(runner, job, timeout_secs).await
}
}
/// Hook for managing supervisor service state
#[hook]
pub fn use_supervisor_service(server_url: &str) -> (Option<SupervisorService>, Option<String>) {
let server_url = server_url.to_string();
let service_state = use_state(|| None);
let error_state = use_state(|| None);
{
let service_state = service_state.clone();
let error_state = error_state.clone();
let server_url = server_url.clone();
use_effect_with(server_url.clone(), move |_| {
spawn_local(async move {
match SupervisorService::new(&server_url) {
Ok(service) => {
service_state.set(Some(service));
error_state.set(None);
}
Err(e) => {
console::error!("Failed to create supervisor service:", e.to_string());
error_state.set(Some(e.to_string()));
}
}
});
});
}
((*service_state).clone(), (*error_state).clone())
}