|
1 | 1 | import { |
| 2 | + createLogger, |
2 | 3 | createRuntimeConfig, |
3 | 4 | RuntimeAgent, |
| 5 | + type RuntimeAgentOptions, |
4 | 6 | type RuntimeConfig, |
5 | 7 | } from "@runt/lib"; |
| 8 | +import * as path from "@std/path"; |
6 | 9 |
|
7 | 10 | export class PythonRuntimeAgent extends RuntimeAgent { |
| 11 | + private kernel: Deno.ChildProcess | null = null; |
| 12 | + private logger = createLogger("python-runtime-agent"); |
8 | 13 | constructor(args: string[] = Deno.args) { |
9 | 14 | let config: RuntimeConfig; |
10 | 15 | try { |
@@ -36,6 +41,54 @@ export class PythonRuntimeAgent extends RuntimeAgent { |
36 | 41 | Deno.exit(1); |
37 | 42 | } |
38 | 43 |
|
39 | | - super(config, config.capabilities, {}); |
| 44 | + super(config, config.capabilities, { |
| 45 | + onStartup: (environmentOptions) => this.onStartup(environmentOptions), |
| 46 | + onShutdown: () => this.onShutdown(), |
| 47 | + }); |
| 48 | + } |
| 49 | + |
| 50 | + private async onStartup( |
| 51 | + options: RuntimeAgentOptions["environmentOptions"], |
| 52 | + ): Promise<void> { |
| 53 | + if (options.runtimeEnvExternallyManaged) { |
| 54 | + const pythonPath = options.runtimePythonPath ?? "python3"; |
| 55 | + const tempDir = await Deno.makeTempDir({ prefix: "anode-kernel" }); |
| 56 | + const connPath = path.join(tempDir, "conn.json"); |
| 57 | + const args = ["-m", "ipykernel_launcher", "-f", connPath]; |
| 58 | + try { |
| 59 | + const command = new Deno.Command(pythonPath, { |
| 60 | + args, |
| 61 | + }); |
| 62 | + this.logger.debug("Starting kernel", { |
| 63 | + python: pythonPath, |
| 64 | + args, |
| 65 | + }); |
| 66 | + this.kernel = command.spawn(); |
| 67 | + this.logger.info("Kernel started", { pid: this.kernel.pid }); |
| 68 | + } finally { |
| 69 | + Deno.removeSync(tempDir, { recursive: true }); |
| 70 | + } |
| 71 | + } else { |
| 72 | + throw new Error("Not yet implemented"); |
| 73 | + } |
| 74 | + } |
| 75 | + |
| 76 | + private async onShutdown(): Promise<void> { |
| 77 | + if (this.kernel) { |
| 78 | + this.logger.info("Shutting down kernel", { pid: this.kernel.pid }); |
| 79 | + try { |
| 80 | + this.kernel.kill(); |
| 81 | + const status = (await this.kernel.status).code; |
| 82 | + this.logger.info("Kernel shutdown", { |
| 83 | + pid: this.kernel.pid, |
| 84 | + status, |
| 85 | + }); |
| 86 | + } catch (error) { |
| 87 | + this.logger.error("Error shutting down kernel", { |
| 88 | + pid: this.kernel.pid, |
| 89 | + error: error instanceof Error ? error.message : String(error), |
| 90 | + }); |
| 91 | + } |
| 92 | + } |
40 | 93 | } |
41 | 94 | } |
0 commit comments