circles/research/launcher
2025-07-09 23:39:48 +02:00
..
examples rename rhai client to dispatcher 2025-07-09 23:39:48 +02:00
src rename rhai client to dispatcher 2025-07-09 23:39:48 +02:00
tests implement stripe and idenfy webhooks support 2025-07-08 22:49:47 +02:00
.gitignore implement stripe and idenfy webhooks support 2025-07-08 22:49:47 +02:00
ARCHITECTURE.md implement stripe and idenfy webhooks support 2025-07-08 22:49:47 +02:00
Cargo.lock rename rhai client to dispatcher 2025-07-09 23:39:48 +02:00
Cargo.toml rename rhai client to dispatcher 2025-07-09 23:39:48 +02:00
circles.json implement stripe and idenfy webhooks support 2025-07-08 22:49:47 +02:00
README.md rename rhai client to dispatcher 2025-07-09 23:39:48 +02:00

Circle Launcher

Crate for launching and managing circle workers and the circles ws server.

Features

  • Single-server multi-circle architecture: One WebSocket server handles all circles via path-based routing
  • Dual operation modes: Direct spawning or service manager integration
  • Initialization scripts: Send Rhai scripts to workers on startup
  • Service management: Automatic restart and background operation support
  • Cross-platform: macOS (launchctl) and Linux (systemd) support
  • Service cleanup: Automatic cleanup of background services on exit

Installation

Build the launcher:

cargo build --release --bin launcher

Usage

Basic Syntax

launcher [OPTIONS] -c <CIRCLE>...

Circle Configuration Format

Circles are specified using the -c/--circle option with the format:

public_key[:init_script.rhai]
  • public_key: secp256k1 public key in hex format (required)
  • init_script.rhai: Optional initialization script to send to the worker

Examples

Development Mode (Direct Spawning)

# Single circle without initialization script
launcher -c 02a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4

# Multiple circles with initialization scripts
launcher -c 02a1b2c3d4e5f6a7...d4:setup.rhai -c 03b2c3d4e5f6a7...e5:config.rhai

# Mixed configuration (some with scripts, some without)
launcher -c 02a1b2c3d4e5f6a7...d4:init.rhai -c 03b2c3d4e5f6a7...e5

Production Mode (Service Manager)

# Using service manager with worker binary
launcher --use-service-manager --worker-binary ./target/release/worker \
  -c 02a1b2c3d4e5f6a7...d4:prod_init.rhai \
  -c 03b2c3d4e5f6a7...e5

# Service manager without initialization scripts
launcher --use-service-manager --worker-binary /usr/local/bin/worker \
  -c 02a1b2c3d4e5f6a7...d4 \
  -c 03b2c3d4e5f6a7...e5

Command Line Options

Option Short Description Default
--circle -c Circle configuration: public_key[:init_script.rhai] Required
--port -p WebSocket server port 8080
--redis-url Redis connection URL redis://127.0.0.1:6379
--enable-auth Enable WebSocket authentication false
--use-service-manager Use service manager instead of direct spawning false
--worker-binary Path to worker binary (required with service manager) None
--debug -d Enable debug logging false
--verbose -v Increase verbosity (can be used multiple times) 0

Operation Modes

Direct Spawn Mode (Default)

In direct spawn mode, workers run as Tokio tasks within the launcher process:

  • Pros: Simple setup, immediate shutdown, ideal for development
  • Cons: Workers stop when launcher exits, no automatic restart
launcher -c 02a1b2c3d4e5f6a7...d4:init.rhai

Service Manager Mode

In service manager mode, workers are managed by the system service manager:

  • Pros: Background operation, automatic restart, production-ready
  • Cons: Requires worker binary, platform-specific setup
launcher --use-service-manager --worker-binary ./target/release/worker \
  -c 02a1b2c3d4e5f6a7...d4:init.rhai

Service Manager Support

  • macOS: Uses launchctl with launch agents
  • Linux: Uses systemd (implementation in progress)

Services are named: tf.ourworld.circles.circle-worker-{public_key}

Architecture

Single-Server Multi-Circle

The launcher creates one WebSocket server that handles multiple circles through path-based routing:

  • Server URL: ws://127.0.0.1:8080
  • Circle URLs: ws://127.0.0.1:8080/{circle_public_key}
  • Worker Queues: rhai_tasks:{circle_public_key}

Initialization Scripts

When a circle configuration includes an initialization script:

  1. Worker starts and connects to Redis
  2. Launcher waits 2 seconds for worker startup
  3. Launcher sends script content via RhaiDispatcher to worker's queue
  4. Worker executes the initialization script

Configuration

Environment Variables

  • RUST_LOG: Controls logging level (auto-configured based on verbosity)
  • PRESERVE_TASKS: Preserve Redis tasks on worker shutdown

Data Directory

The launcher creates a ./launch_data directory for:

  • Worker databases: circle_db_{public_key}.db
  • Service configuration files (service manager mode)

Error Handling

Common error scenarios and solutions:

Error Cause Solution
"Invalid public key" Malformed secp256k1 key Verify key format (64 hex chars)
"Worker binary path required" Missing --worker-binary in service mode Provide path to worker executable
"Failed to read init script" Script file not found Check script file path and permissions
"Service already exists" Service name conflict Stop existing service or use different key

Development

Building

# Debug build
cargo build --bin launcher

# Release build
cargo build --release --bin launcher

Testing

# Run with debug logging
RUST_LOG=debug cargo run --bin launcher -- -c 02a1b2c3d4e5f6a7...d4

# Test service manager mode
cargo run --bin launcher -- --use-service-manager \
  --worker-binary ./target/debug/worker \
  -c 02a1b2c3d4e5f6a7...d4:test.rhai

Troubleshooting

Worker Connection Issues

  1. Verify Redis is running on the specified URL
  2. Check worker binary exists and is executable
  3. Ensure public keys are valid secp256k1 format

Service Manager Issues

  1. Check service manager logs: launchctl log show --predicate 'subsystem == "tf.ourworld.circles"'
  2. Verify worker binary permissions and dependencies
  3. Ensure working directory is accessible

Script Execution Issues

  1. Verify script file exists and is readable
  2. Check Redis connectivity for script transmission
  3. Monitor worker logs for script execution errors

Security Considerations

  • Public Key Validation: All keys are validated as proper secp256k1 public keys
  • Script Execution: Initialization scripts run with worker privileges
  • Service Isolation: Each worker runs as a separate service in service manager mode
  • Redis Security: Ensure Redis instance is properly secured in production

Performance

  • Concurrent Workers: No hard limit on number of circles
  • Resource Usage: Each worker consumes memory for database and Rhai engine
  • Network: Single WebSocket server reduces port usage
  • Startup Time: ~2 second delay for initialization script transmission

Service Cleanup

The launcher provides automatic cleanup functionality to stop and remove all circle-related services:

Automatic Cleanup

Examples automatically clean up services on exit:

# Run example - services are cleaned up automatically on exit or Ctrl+C
cargo run --example circle_launcher_example

Manual Cleanup

Clean up all circle services manually:

# Using the cleanup example
cargo run --example cleanup_example

# Or using the library function
use circles_launcher::cleanup_launcher;
cleanup_launcher().await?;

What Gets Cleaned Up

The cleanup function removes:

  • All worker services (circle-worker-{public_key})
  • WebSocket server service (circle-ws-server)
  • Associated service configuration files (plist files on macOS)

Signal Handling

Examples include signal handling for graceful cleanup:

  • Ctrl+C: Triggers cleanup before exit
  • Normal exit: Always runs cleanup before termination
  • Error exit: Cleanup still runs to prevent orphaned services