# `launcher` Architecture This document provides a detailed look into the internal architecture of the `launcher` utility, explaining how it orchestrates the creation and management of multiple Circle instances. ## 1. Core Design The `launcher` is a `tokio`-based asynchronous application. Its primary responsibility is to parse a configuration file and then spawn and manage the lifecycle of two key components for each configured Circle: 1. **A `server` instance**: A WebSocket server running in its own `tokio` task. 2. **A Rhai worker**: A script execution engine running in a separate `tokio` task. The launcher maintains a central registry of all running circles, allowing it to monitor their status and coordinate a graceful shutdown. ## 2. Startup and Initialization Sequence The `main` function in `launcher/src/main.rs` executes the following sequence: 1. **Parse Command-Line Arguments**: It checks for verbosity flags (`-v`, `-vv`, `-vvv`) and a debug flag (`-d`) to configure the logging level. 2. **Load Configuration**: It reads and deserializes the `circles.json` file into a `Vec`. 3. **Iterate and Spawn**: For each `CircleConfig` in the vector, it performs the following steps: a. **Database Setup**: It creates a dedicated database directory for the Circle at `~/.hero/circles/{id}/`. b. **Rhai Engine Initialization**: It creates an instance of the Rhai engine and, if a `script_path` is provided, executes the initial script. c. **Worker Spawning**: It calls `worker_lib::spawn_rhai_worker`, which starts the Rhai worker in a new `tokio` task. It provides the worker with a shutdown channel receiver. d. **Server Spawning**: It calls `circle_ws_lib::spawn_circle_ws_server`, which starts the `Actix` WebSocket server in another `tokio` task. It provides the server with a channel to send back its `ServerHandle`. 4. **Store Handles**: It stores all the necessary handles for each running circle—including the worker's shutdown channel sender and the server's `ServerHandle`—in a central `Vec`. 5. **Display Status**: It prints a table to the console with details about each running circle. ## 3. Graceful Shutdown The launcher is designed to shut down all its child processes cleanly when it receives a `Ctrl+C` signal. ```mermaid sequenceDiagram participant User participant Launcher as main() participant Worker as Rhai Worker Task participant Server as WS Server Task User->>Launcher: Presses Ctrl+C Launcher->>Launcher: Catches signal::ctrl_c() loop For Each Running Circle Launcher->>Worker: Sends shutdown signal via mpsc::channel Launcher->>Server: Calls handle.stop(true) end Note over Launcher: Waits for all tasks to complete. Launcher->>User: Exits cleanly ``` This process ensures that both the WebSocket servers and the Rhai workers have a chance to terminate properly, preventing orphaned processes and potential data corruption.