sal/examples/service_manager/README.md
Mahmoud-Emad 131d978450 feat: Add service manager support
- Add a new service manager crate for dynamic service management
- Integrate service manager with Rhai for scripting
- Provide examples for circle worker management and basic usage
- Add comprehensive tests for service lifecycle and error handling
- Implement cross-platform support for macOS and Linux (zinit/systemd)
2025-07-01 18:00:21 +03:00

3.6 KiB

Service Manager Examples

This directory contains examples demonstrating the SAL service manager functionality for dynamically launching and managing services across platforms.

Overview

The service manager provides a unified interface for managing system services:

  • macOS: Uses launchctl for service management
  • Linux: Uses zinit for service management (systemd also available as alternative)

Examples

1. Circle Worker Manager (circle_worker_manager.rhai)

Primary Use Case: Demonstrates dynamic circle worker management for freezone residents.

This example shows:

  • Creating service configurations for circle workers
  • Complete service lifecycle management (start, stop, restart, remove)
  • Status monitoring and log retrieval
  • Error handling and cleanup
# Run the circle worker management example
herodo examples/service_manager/circle_worker_manager.rhai

2. Basic Usage (basic_usage.rhai)

Learning Example: Simple demonstration of the core service manager API.

This example covers:

  • Creating and configuring services
  • Starting and stopping services
  • Checking service status
  • Listing managed services
  • Retrieving service logs
# Run the basic usage example
herodo examples/service_manager/basic_usage.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.

Service Manager API

The service manager provides these key functions:

  • create_service_manager() - Create platform-appropriate service manager
  • start(manager, config) - Start a new service
  • stop(manager, service_name) - Stop a running service
  • restart(manager, service_name) - Restart a service
  • status(manager, service_name) - Get service status
  • logs(manager, service_name, lines) - Retrieve service logs
  • list(manager) - List all managed services
  • remove(manager, service_name) - Remove a service
  • exists(manager, service_name) - Check if service exists
  • start_and_confirm(manager, config, timeout) - Start with confirmation

Service Configuration

Services are configured using a map with these fields:

let config = #{
    name: "my-service",                    // Service name
    binary_path: "/usr/bin/my-app",        // Executable path
    args: ["--config", "/etc/my-app.conf"], // Command arguments
    working_directory: "/var/lib/my-app",   // Working directory (optional)
    environment: #{                         // Environment variables
        "VAR1": "value1",
        "VAR2": "value2"
    },
    auto_restart: true                      // Auto-restart on failure
};

Real-World Usage

The circle worker example demonstrates the exact use case requested by the team:

"We want to be able to launch circle workers dynamically. For instance when someone registers to the freezone, we need to be able to launch a circle worker for the new resident."

The service manager enables:

  1. Dynamic service creation - Create services on-demand for new residents
  2. Cross-platform support - Works on both macOS and Linux
  3. Lifecycle management - Full control over service lifecycle
  4. Monitoring and logging - Track service status and retrieve logs
  5. Cleanup - Proper service removal when no longer needed

Error Handling

All service manager functions can throw errors. Use try-catch blocks for robust error handling:

try {
    sm::start(manager, config);
    print("✅ Service started successfully");
} catch (error) {
    print(`❌ Failed to start service: ${error}`);
}