sal/service_manager
Mahmoud-Emad 352e846410 feat: Improve Zinit service manager integration
- Handle arguments and working directory correctly in Zinit: The
  Zinit service manager now correctly handles arguments and
  working directories passed to services, ensuring consistent
  behavior across different service managers.  This fixes issues
  where commands would fail due to incorrect argument parsing or
  missing working directory settings.

- Simplify Zinit service configuration: The Zinit service
  configuration is now simplified, using a more concise and
  readable format. This improves maintainability and reduces the
  complexity of the service configuration process.

- Refactor Zinit service start: This refactors the Zinit service
  start functionality for better readability and maintainability.
  The changes improve the code structure and reduce the complexity
  of the code.
2025-07-02 13:39:11 +03:00
..
examples feat: Improve service manager testing and error handling 2025-07-02 12:05:03 +03:00
src feat: Improve Zinit service manager integration 2025-07-02 13:39:11 +03:00
tests feat: Improve Zinit service manager integration 2025-07-02 13:39:11 +03:00
Cargo.toml feat: Add service manager support 2025-07-01 18:00:21 +03:00
README.md feat: Improve service manager testing and error handling 2025-07-02 12:05:03 +03:00

SAL Service Manager

Crates.io Documentation

A cross-platform service management library for the System Abstraction Layer (SAL). This crate provides a unified interface for managing system services across different platforms, enabling dynamic deployment of workers and services.

Features

  • Cross-platform service management - Unified API across macOS and Linux
  • Dynamic worker deployment - Perfect for circle workers and on-demand services
  • Platform-specific implementations:
    • macOS: Uses launchctl with plist management
    • Linux: Uses zinit for lightweight service management (systemd also available)
  • Complete lifecycle management - Start, stop, restart, status monitoring, and log retrieval
  • Service configuration - Environment variables, working directories, auto-restart
  • Production-ready - Comprehensive error handling and resource management

Usage

Add this to your Cargo.toml:

[dependencies]
sal-service-manager = "0.1.0"

Or use it as part of the SAL ecosystem:

[dependencies]
sal = { version = "0.1.0", features = ["service_manager"] }

Primary Use Case: Dynamic Circle Worker Management

This service manager was designed specifically for dynamic deployment of circle workers in freezone environments. When a new resident registers, you can instantly launch a dedicated circle worker:

use sal_service_manager::{create_service_manager, ServiceConfig};
use std::collections::HashMap;

// New resident registration triggers worker creation
fn deploy_circle_worker(resident_id: &str) -> Result<(), Box<dyn std::error::Error>> {
    let manager = create_service_manager();

    let mut env = HashMap::new();
    env.insert("RESIDENT_ID".to_string(), resident_id.to_string());
    env.insert("WORKER_TYPE".to_string(), "circle".to_string());

    let config = ServiceConfig {
        name: format!("circle-worker-{}", resident_id),
        binary_path: "/usr/bin/circle-worker".to_string(),
        args: vec!["--resident".to_string(), resident_id.to_string()],
        working_directory: Some("/var/lib/circle-workers".to_string()),
        environment: env,
        auto_restart: true,
    };

    // Deploy the worker
    manager.start(&config)?;
    println!("✅ Circle worker deployed for resident: {}", resident_id);

    Ok(())
}

Basic Usage Example

Here is an example of the core service management API:

use sal_service_manager::{create_service_manager, ServiceConfig};
use std::collections::HashMap;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let service_manager = create_service_manager();

    let config = ServiceConfig {
        name: "my-service".to_string(),
        binary_path: "/usr/local/bin/my-service-executable".to_string(),
        args: vec!["--config".to_string(), "/etc/my-service.conf".to_string()],
        working_directory: Some("/var/tmp".to_string()),
        environment: HashMap::new(),
        auto_restart: true,
    };

    // Start a new service
    service_manager.start(&config)?;

    // Get the status of the service
    let status = service_manager.status("my-service")?;
    println!("Service status: {:?}", status);

    // Stop the service
    service_manager.stop("my-service")?;

    Ok(())
}

Examples

Comprehensive examples are available in the SAL examples directory:

Circle Worker Manager Example

The primary use case - dynamically launching circle workers for new freezone residents:

# Run the circle worker management example
herodo examples/service_manager/circle_worker_manager.rhai

This example demonstrates:

  • Creating service configurations for circle workers
  • Complete service lifecycle management
  • Error handling and status monitoring
  • Service cleanup and removal

Basic Usage Example

A simpler example showing the core API:

# Run the basic usage example
herodo examples/service_manager/basic_usage.rhai

See examples/service_manager/README.md for detailed documentation.

Testing

Run the test suite:

cargo test -p sal-service-manager

For Rhai integration tests:

cargo test -p sal-service-manager --features rhai

Testing with Herodo

To test the service manager with real Rhai scripts using herodo, first build herodo:

./build_herodo.sh

Then run Rhai scripts that use the service manager:

herodo your_service_script.rhai

Prerequisites

Linux (zinit)

Make sure zinit is installed and running:

# Start zinit with default socket
zinit -s /tmp/zinit.sock init

macOS (launchctl)

No additional setup required - uses the built-in launchctl system.

Platform Support

  • macOS: Full support using launchctl for service management
  • Linux: Full support using zinit for service management (systemd also available as alternative)
  • Windows: Not currently supported