cleanup and refactor

This commit is contained in:
Timur Gordon
2025-11-13 14:41:30 +01:00
parent 4b516d9d7e
commit 2625534152
29 changed files with 2662 additions and 3276 deletions

268
_archive/services.rs Normal file
View File

@@ -0,0 +1,268 @@
//! Service layer for persistent storage of keys, runners, and jobs
//!
//! This module provides database/storage services for the supervisor.
//! Currently uses in-memory storage, but designed to be easily extended
//! to use Redis, PostgreSQL, or other persistent storage backends.
use crate::auth::{ApiKey, ApiKeyScope};
use hero_job::Job;
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::Mutex;
use serde::{Deserialize, Serialize};
/// Service for managing API keys
#[derive(Debug, Clone)]
pub struct ApiKeyService {
store: Arc<Mutex<HashMap<String, ApiKey>>>,
}
impl ApiKeyService {
/// Create a new API key service
pub fn new() -> Self {
Self {
store: Arc::new(Mutex::new(HashMap::new())),
}
}
/// Store an API key
pub async fn store(&self, key: ApiKey) -> Result<(), String> {
let mut store = self.store.lock().await;
store.insert(key.key.clone(), key);
Ok(())
}
/// Get an API key by its key string
pub async fn get(&self, key: &str) -> Option<ApiKey> {
let store = self.store.lock().await;
store.get(key).cloned()
}
/// List all API keys
pub async fn list(&self) -> Vec<ApiKey> {
let store = self.store.lock().await;
store.values().cloned().collect()
}
/// Remove an API key
pub async fn remove(&self, key: &str) -> Option<ApiKey> {
let mut store = self.store.lock().await;
store.remove(key)
}
/// Count API keys by scope
pub async fn count_by_scope(&self, scope: ApiKeyScope) -> usize {
let store = self.store.lock().await;
store.values().filter(|k| k.scope == scope).count()
}
/// Clear all API keys (for testing)
pub async fn clear(&self) {
let mut store = self.store.lock().await;
store.clear();
}
}
impl Default for ApiKeyService {
fn default() -> Self {
Self::new()
}
}
/// Service for managing runners
#[derive(Debug, Clone)]
pub struct RunnerService {
store: Arc<Mutex<HashMap<String, RunnerMetadata>>>,
}
/// Metadata about a runner for storage
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RunnerMetadata {
pub id: String,
pub name: String,
pub queue: String,
pub registered_at: String,
pub registered_by: String, // API key name that registered this runner
}
impl RunnerService {
/// Create a new runner service
pub fn new() -> Self {
Self {
store: Arc::new(Mutex::new(HashMap::new())),
}
}
/// Store runner metadata
pub async fn store(&self, metadata: RunnerMetadata) -> Result<(), String> {
let mut store = self.store.lock().await;
store.insert(metadata.id.clone(), metadata);
Ok(())
}
/// Get runner metadata by ID
pub async fn get(&self, id: &str) -> Option<RunnerMetadata> {
let store = self.store.lock().await;
store.get(id).cloned()
}
/// List all runners
pub async fn list(&self) -> Vec<RunnerMetadata> {
let store = self.store.lock().await;
store.values().cloned().collect()
}
/// Remove a runner
pub async fn remove(&self, id: &str) -> Option<RunnerMetadata> {
let mut store = self.store.lock().await;
store.remove(id)
}
/// Count total runners
pub async fn count(&self) -> usize {
let store = self.store.lock().await;
store.len()
}
/// Clear all runners (for testing)
pub async fn clear(&self) {
let mut store = self.store.lock().await;
store.clear();
}
}
impl Default for RunnerService {
fn default() -> Self {
Self::new()
}
}
/// Service for managing jobs
#[derive(Debug, Clone)]
pub struct JobService {
store: Arc<Mutex<HashMap<String, JobMetadata>>>,
}
/// Metadata about a job for storage
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct JobMetadata {
pub job_id: String,
pub runner: String,
pub created_at: String,
pub created_by: String, // API key name that created this job
pub status: String,
pub job: Job,
}
impl JobService {
/// Create a new job service
pub fn new() -> Self {
Self {
store: Arc::new(Mutex::new(HashMap::new())),
}
}
/// Store job metadata
pub async fn store(&self, metadata: JobMetadata) -> Result<(), String> {
let mut store = self.store.lock().await;
store.insert(metadata.job_id.clone(), metadata);
Ok(())
}
/// Get job metadata by ID
pub async fn get(&self, job_id: &str) -> Option<JobMetadata> {
let store = self.store.lock().await;
store.get(job_id).cloned()
}
/// List all jobs
pub async fn list(&self) -> Vec<JobMetadata> {
let store = self.store.lock().await;
store.values().cloned().collect()
}
/// List jobs by runner
pub async fn list_by_runner(&self, runner: &str) -> Vec<JobMetadata> {
let store = self.store.lock().await;
store.values()
.filter(|j| j.runner == runner)
.cloned()
.collect()
}
/// List jobs by creator (API key name)
pub async fn list_by_creator(&self, creator: &str) -> Vec<JobMetadata> {
let store = self.store.lock().await;
store.values()
.filter(|j| j.created_by == creator)
.cloned()
.collect()
}
/// Update job status
pub async fn update_status(&self, job_id: &str, status: String) -> Result<(), String> {
let mut store = self.store.lock().await;
if let Some(metadata) = store.get_mut(job_id) {
metadata.status = status;
Ok(())
} else {
Err(format!("Job not found: {}", job_id))
}
}
/// Remove a job
pub async fn remove(&self, job_id: &str) -> Option<JobMetadata> {
let mut store = self.store.lock().await;
store.remove(job_id)
}
/// Count total jobs
pub async fn count(&self) -> usize {
let store = self.store.lock().await;
store.len()
}
/// Clear all jobs (for testing)
pub async fn clear(&self) {
let mut store = self.store.lock().await;
store.clear();
}
}
impl Default for JobService {
fn default() -> Self {
Self::new()
}
}
/// Combined service container for all storage services
#[derive(Debug, Clone)]
pub struct Services {
pub api_keys: ApiKeyService,
pub runners: RunnerService,
pub jobs: JobService,
}
impl Services {
/// Create a new services container
pub fn new() -> Self {
Self {
api_keys: ApiKeyService::new(),
runners: RunnerService::new(),
jobs: JobService::new(),
}
}
/// Clear all data (for testing)
pub async fn clear_all(&self) {
self.api_keys.clear().await;
self.runners.clear().await;
self.jobs.clear().await;
}
}
impl Default for Services {
fn default() -> Self {
Self::new()
}
}