// 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", }); // Create a pool of workers. const workerPool: { worker: Worker; inUse: boolean }[] = []; const numWorkers = navigator.hardwareConcurrency; for (let i = 0; i < numWorkers; i++) { const worker = new Worker(new URL("./worker.ts", import.meta.url).href, { type: "module", deno: { namespace: true, permissions: "inherit", }, }); workerPool.push({ worker, inUse: false }); } function getAvailableWorker() { return new Promise((resolve) => { const check = () => { const availableWorker = workerPool.find((w) => !w.inUse); if (availableWorker) { availableWorker.inUse = true; resolve(availableWorker); } else { setTimeout(check, 100); // Check again in 100ms. } }; check(); }); } async function handler(req: Request): Promise { if (req.method !== "POST" || new URL(req.url).pathname !== "/execute") { return new Response("Not Found", { status: 404 }); } const availableWorker = (await getAvailableWorker()) as { worker: Worker; inUse: boolean; }; try { const body = await req.json(); const { code = "", request = {}, environment = {}, name } = body; const executionPromise = new Promise((resolve, reject) => { availableWorker.worker.onmessage = (e) => { resolve(e.data); }; availableWorker.worker.onerror = (e) => { reject(new Error(`Worker error: ${e.message}`)); }; }); const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error("Timeout")), TIMEOUT_MS) ); availableWorker.worker.postMessage({ code, request, environment, name }); const startTime = performance.now(); try { const result = await Promise.race([executionPromise, timeoutPromise]); return new Response(JSON.stringify(result), { headers: { "Content-Type": "application/json" }, }); } catch (err) { const executionTime = performance.now() - startTime; const payload = { status: States.TIMEOUT, 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 { availableWorker.inUse = false; // Release the worker. } } console.log(`⚡ Deno server ready on :8000 with ${numWorkers} workers.`); await serve(handler, { port: 8000 });