/ actors / manager.ts
manager.ts
  1  import { Task } from "../lib.ts";
  2  import type { Actor } from "./core/types.ts";
  3  
  4  /**
  5   * Actor Manager - spawns and manages multiple actors
  6   * Extracted from the original actors-main.ts for reusability
  7   */
  8  export class ActorManager {
  9    private actors: Actor[] = [];
 10    private tasks: Task.Invocation<void, Error>[] = [];
 11  
 12    /**
 13     * Add an actor to the manager
 14     */
 15    addActor(actor: Actor): ActorManager {
 16      this.actors.push(actor);
 17      return this;
 18    }
 19  
 20    /**
 21     * Add multiple actors to the manager
 22     */
 23    addActors(actors: Actor[]): ActorManager {
 24      this.actors.push(...actors);
 25      return this;
 26    }
 27  
 28    /**
 29     * Get the list of managed actors
 30     */
 31    getActors(): Actor[] {
 32      return [...this.actors];
 33    }
 34  
 35    /**
 36     * Start all actors concurrently
 37     */
 38    *startAll(): Task.Task<void, Error> {
 39      console.log(`šŸŽ¬ Starting ${this.actors.length} actors...`);
 40      
 41      // Start all actors concurrently
 42      for (const actor of this.actors) {
 43        const task = actor.start();
 44        this.tasks.push(task);
 45      }
 46      
 47      console.log("šŸƒ All actors started!");
 48      console.log("Press Ctrl+C to stop all actors");
 49      
 50      // Set up graceful shutdown
 51      this.setupShutdownHandlers();
 52      
 53      // Wait for all tasks to complete (they won't unless stopped)
 54      yield* Task.wait(Promise.all(this.tasks.map(task => Task.spawn(function*() {
 55        try {
 56          yield* task;
 57        } catch (error) {
 58          console.error("āŒ Actor error:", error);
 59        }
 60      }))));
 61    }
 62  
 63    /**
 64     * Stop all actors
 65     */
 66    stopAll(): void {
 67      console.log("šŸ›‘ Stopping all actors...");
 68      for (const actor of this.actors) {
 69        actor.stop();
 70      }
 71    }
 72  
 73    /**
 74     * Get count of actors by name pattern
 75     */
 76    getActorCount(): number {
 77      return this.actors.length;
 78    }
 79  
 80    /**
 81     * List all actor names
 82     */
 83    getActorNames(): string[] {
 84      return this.actors.map(actor => actor.getName());
 85    }
 86  
 87    /**
 88     * Set up handlers for graceful shutdown
 89     */
 90    private setupShutdownHandlers(): void {
 91      const shutdown = () => {
 92        console.log("\nšŸ‘‹ Graceful shutdown initiated...");
 93        this.stopAll();
 94        setTimeout(() => {
 95          console.log("🚪 Exiting...");
 96          Deno.exit(0);
 97        }, 2000); // Give actors 2 seconds to clean up
 98      };
 99  
100      // Handle Ctrl+C
101      Deno.addSignalListener("SIGINT", shutdown);
102      
103      // Handle other termination signals
104      try {
105        Deno.addSignalListener("SIGTERM", shutdown);
106      } catch {
107        // SIGTERM might not be available on all platforms
108      }
109    }
110  }