// isolator/deno_server.ts import { serve } from "https://deno.land/std@0.201.0/http/server.ts"; const TIMEOUT_MS = 5_000; const States = Object.freeze({ TIMEOUT: "TIMEOUT", }); async function handler(req: Request): Promise { if (req.method !== "POST" || new URL(req.url).pathname !== "/execute") { return new Response("Not Found", { status: 404 }); } // For each request, spawn a new worker, use it, and then terminate it. // This ensures a clean, stateless environment for every execution. const worker = new Worker(new URL("./worker.ts", import.meta.url).href, { type: "module", deno: { namespace: true, permissions: "inherit", }, }); try { const body = await req.json(); const { code = "", request = {}, environment = {}, name = "userFunc", } = body; const executionPromise = new Promise((resolve, reject) => { let timeoutId: number; const cleanup = () => { worker.removeEventListener("message", messageHandler); worker.removeEventListener("error", errorHandler); if (timeoutId) clearTimeout(timeoutId); }; const messageHandler = (e: MessageEvent) => { cleanup(); resolve(e.data); }; const errorHandler = (e: ErrorEvent) => { cleanup(); reject(new Error(`Worker error: ${e.message}`)); }; timeoutId = setTimeout(() => { cleanup(); reject(new Error("Timeout")); }, TIMEOUT_MS); worker.addEventListener("message", messageHandler); worker.addEventListener("error", errorHandler); worker.postMessage({ code, request, environment, name }); }); const startTime = performance.now(); try { const result = await executionPromise; return new Response(JSON.stringify(result), { headers: { "Content-Type": "application/json" }, }); } catch (err) { const executionTime = performance.now() - startTime; const payload = { status: err.message === "Timeout" ? States.TIMEOUT : "ERROR", result: err.message, logs: [], environment: environment, execution_time: executionTime, }; return new Response(JSON.stringify(payload), { status: 500, headers: { "Content-Type": "application/json" }, }); } } catch (e) { return new Response(`Bad Request: ${e.message}`, { status: 400 }); } finally { worker.terminate(); // Ensure the worker is always terminated. } } const port = parseInt(Deno.env.get("PORT") || "8000"); console.log(`⚡ Deno server ready on :${port}`); await serve(handler, { port });