sharp by wasm

This commit is contained in:
seb
2026-10-28 01:46:51 +01:00
parent 1c5385061c
commit e7884c03ef
20 changed files with 530 additions and 364 deletions

View File

@@ -2,7 +2,7 @@ import { Worker } from 'worker_threads';
import { fileURLToPath } from 'url';
import env from '../config/env.js';
// The sandbox worker pays a large fixed startup cost: importing vm2, sharp, exceljs, pdfkit,
// The sandbox worker pays a large fixed startup cost: importing vm2, wasm-image-optimization, exceljs, pdfkit,
// react-canvas-label-editor AND `vfs.js` (which pulls in libdashstore) costs ~700 ms in a fresh
// thread, while the snippet itself runs in ~2 ms. ESM modules are never shared between worker
// threads, so spawning one thread per applet run re-paid that cost on every request.
@@ -17,7 +17,7 @@ const WORKER_BOOT_TIMEOUT_MS = 15000;
// Two threads per company rides out the common "run it, then run it again" loop without queueing.
const MAX_WORKERS_PER_COMPANY = 2;
// ...but the process is shared by every company, so the total stays bounded. Each thread holds
// sharp/libvips plus a NodeVM, so 5 is a deliberate memory ceiling rather than a core count.
// WASM modules plus a NodeVM, so 5 is a deliberate memory ceiling rather than a core count.
const MAX_WORKERS_TOTAL = 5;
const DEFAULT_BUFFER_LIMIT = 32 * 1024 * 1024;
@@ -228,7 +228,7 @@ function runJobOnWorker(entry, job, timeoutMs) {
let settled = false;
const timer = setTimeout(() => {
// Terminate first, then report. A snippet stuck in a native call (libvips, fetch)
// Terminate first, then report. A snippet stuck in a WASM or I/O call (optimizeImage, fetch)
// would otherwise keep burning the thread after the caller has moved on, and its
// eventual reply would arrive against an already-settled job.
try { entry.worker.terminate(); } catch { /* already closed */ }