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 }