From 0209d331f48f63f30cdcd44ee4ff5cbbc0638dba Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Fri, 6 Feb 2026 16:35:20 -0800 Subject: [PATCH] fix fallbacks --- apps/sim/lib/execution/isolated-vm.test.ts | 14 ++--- apps/sim/lib/execution/isolated-vm.ts | 61 ++++++++++++---------- 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/apps/sim/lib/execution/isolated-vm.test.ts b/apps/sim/lib/execution/isolated-vm.test.ts index ad5023e4d..17fb20c0d 100644 --- a/apps/sim/lib/execution/isolated-vm.test.ts +++ b/apps/sim/lib/execution/isolated-vm.test.ts @@ -247,10 +247,10 @@ describe('isolated-vm scheduler', () => { ownerKey: 'user:b', }) - expect(second.error?.name).toBe('QueueFullError') + expect(second.error?.message).toContain('at capacity') const first = await firstPromise - expect(first.error?.name).toBe('QueueTimeoutError') + expect(first.error?.message).toContain('timed out waiting') }) it('enforces per-owner queued limit', async () => { @@ -284,10 +284,10 @@ describe('isolated-vm scheduler', () => { ownerKey: 'user:hog', }) - expect(second.error?.name).toBe('OwnerQueueLimitError') + expect(second.error?.message).toContain('Too many concurrent') const first = await firstPromise - expect(first.error?.name).toBe('QueueTimeoutError') + expect(first.error?.message).toContain('timed out waiting') }) it('enforces distributed owner in-flight lease limit when Redis is configured', async () => { @@ -316,7 +316,7 @@ describe('isolated-vm scheduler', () => { ownerKey: 'user:distributed', }) - expect(result.error?.name).toBe('OwnerInFlightLimitError') + expect(result.error?.message).toContain('Too many concurrent') }) it('fails closed when Redis is configured but unavailable', async () => { @@ -337,7 +337,7 @@ describe('isolated-vm scheduler', () => { ownerKey: 'user:redis-down', }) - expect(result.error?.name).toBe('DistributedFairnessUnavailableError') + expect(result.error?.message).toContain('temporarily unavailable') }) it('fails closed when Redis lease evaluation errors', async () => { @@ -365,7 +365,7 @@ describe('isolated-vm scheduler', () => { ownerKey: 'user:redis-error', }) - expect(result.error?.name).toBe('DistributedFairnessUnavailableError') + expect(result.error?.message).toContain('temporarily unavailable') }) it('applies weighted owner scheduling when draining queued executions', async () => { diff --git a/apps/sim/lib/execution/isolated-vm.ts b/apps/sim/lib/execution/isolated-vm.ts index 42870dce2..c408a3c32 100644 --- a/apps/sim/lib/execution/isolated-vm.ts +++ b/apps/sim/lib/execution/isolated-vm.ts @@ -52,23 +52,24 @@ export interface IsolatedVMError { lineContent?: string } -const POOL_SIZE = Number.parseInt(env.IVM_POOL_SIZE) -const MAX_CONCURRENT = Number.parseInt(env.IVM_MAX_CONCURRENT) -const MAX_PER_WORKER = Number.parseInt(env.IVM_MAX_PER_WORKER) -const WORKER_IDLE_TIMEOUT_MS = Number.parseInt(env.IVM_WORKER_IDLE_TIMEOUT_MS) -const QUEUE_TIMEOUT_MS = Number.parseInt(env.IVM_QUEUE_TIMEOUT_MS) -const MAX_QUEUE_SIZE = Number.parseInt(env.IVM_MAX_QUEUE_SIZE) -const MAX_FETCH_RESPONSE_BYTES = Number.parseInt(env.IVM_MAX_FETCH_RESPONSE_BYTES) -const MAX_FETCH_RESPONSE_CHARS = Number.parseInt(env.IVM_MAX_FETCH_RESPONSE_CHARS) -const MAX_FETCH_URL_LENGTH = Number.parseInt(env.IVM_MAX_FETCH_URL_LENGTH) -const MAX_FETCH_OPTIONS_JSON_CHARS = Number.parseInt(env.IVM_MAX_FETCH_OPTIONS_JSON_CHARS) -const MAX_ACTIVE_PER_OWNER = Number.parseInt(env.IVM_MAX_ACTIVE_PER_OWNER) -const MAX_QUEUED_PER_OWNER = Number.parseInt(env.IVM_MAX_QUEUED_PER_OWNER) -const MAX_OWNER_WEIGHT = Number.parseInt(env.IVM_MAX_OWNER_WEIGHT) -const DISTRIBUTED_MAX_INFLIGHT_PER_OWNER = Number.parseInt( - env.IVM_DISTRIBUTED_MAX_INFLIGHT_PER_OWNER -) -const DISTRIBUTED_LEASE_MIN_TTL_MS = Number.parseInt(env.IVM_DISTRIBUTED_LEASE_MIN_TTL_MS) +const POOL_SIZE = Number.parseInt(env.IVM_POOL_SIZE) || 4 +const MAX_CONCURRENT = Number.parseInt(env.IVM_MAX_CONCURRENT) || 10000 +const MAX_PER_WORKER = Number.parseInt(env.IVM_MAX_PER_WORKER) || 2500 +const WORKER_IDLE_TIMEOUT_MS = Number.parseInt(env.IVM_WORKER_IDLE_TIMEOUT_MS) || 60000 +const QUEUE_TIMEOUT_MS = Number.parseInt(env.IVM_QUEUE_TIMEOUT_MS) || 300000 +const MAX_QUEUE_SIZE = Number.parseInt(env.IVM_MAX_QUEUE_SIZE) || 10000 +const MAX_FETCH_RESPONSE_BYTES = Number.parseInt(env.IVM_MAX_FETCH_RESPONSE_BYTES) || 8_388_608 +const MAX_FETCH_RESPONSE_CHARS = Number.parseInt(env.IVM_MAX_FETCH_RESPONSE_CHARS) || 4_000_000 +const MAX_FETCH_URL_LENGTH = Number.parseInt(env.IVM_MAX_FETCH_URL_LENGTH) || 8192 +const MAX_FETCH_OPTIONS_JSON_CHARS = + Number.parseInt(env.IVM_MAX_FETCH_OPTIONS_JSON_CHARS) || 262_144 +const MAX_ACTIVE_PER_OWNER = Number.parseInt(env.IVM_MAX_ACTIVE_PER_OWNER) || 200 +const MAX_QUEUED_PER_OWNER = Number.parseInt(env.IVM_MAX_QUEUED_PER_OWNER) || 2000 +const MAX_OWNER_WEIGHT = Number.parseInt(env.IVM_MAX_OWNER_WEIGHT) || 5 +const DISTRIBUTED_MAX_INFLIGHT_PER_OWNER = + Number.parseInt(env.IVM_DISTRIBUTED_MAX_INFLIGHT_PER_OWNER) || + MAX_ACTIVE_PER_OWNER + MAX_QUEUED_PER_OWNER +const DISTRIBUTED_LEASE_MIN_TTL_MS = Number.parseInt(env.IVM_DISTRIBUTED_LEASE_MIN_TTL_MS) || 120000 const DISTRIBUTED_KEY_PREFIX = 'ivm:fair:v1:owner' const QUEUE_RETRY_DELAY_MS = 1000 const DISTRIBUTED_LEASE_GRACE_MS = 30000 @@ -611,7 +612,7 @@ function cleanupWorker(workerId: number) { pending.resolve({ result: null, stdout: '', - error: { message: 'Worker process exited unexpectedly', name: 'WorkerError' }, + error: { message: 'Code execution failed unexpectedly. Please try again.', name: 'Error' }, }) workerInfo.pendingExecutions.delete(id) } @@ -848,7 +849,7 @@ function dispatchToWorker( resolve({ result: null, stdout: '', - error: { message: 'Failed to send execution request to worker', name: 'WorkerError' }, + error: { message: 'Code execution failed to start. Please try again.', name: 'Error' }, }) resetWorkerIdleTimeout(workerInfo.id) // Defer to break synchronous recursion: drainQueue → dispatchToWorker → catch → drainQueue @@ -866,8 +867,8 @@ function enqueueExecution( result: null, stdout: '', error: { - message: `Execution queue is full (${MAX_QUEUE_SIZE}). Please retry later.`, - name: 'QueueFullError', + message: 'Code execution is at capacity. Please try again in a moment.', + name: 'Error', }, }) return @@ -877,8 +878,9 @@ function enqueueExecution( result: null, stdout: '', error: { - message: `Owner queue limit reached (${MAX_QUEUED_PER_OWNER}). Please retry later.`, - name: 'OwnerQueueLimitError', + message: + 'Too many concurrent code executions. Please wait for some to complete before running more.', + name: 'Error', }, }) return @@ -892,8 +894,8 @@ function enqueueExecution( result: null, stdout: '', error: { - message: `Execution queued too long (${QUEUE_TIMEOUT_MS}ms). All workers are busy.`, - name: 'QueueTimeoutError', + message: 'Code execution timed out waiting for an available worker. Please try again.', + name: 'Error', }, }) }, QUEUE_TIMEOUT_MS) @@ -973,8 +975,9 @@ export async function executeInIsolatedVM( result: null, stdout: '', error: { - message: `Owner in-flight limit reached (${DISTRIBUTED_MAX_INFLIGHT_PER_OWNER}). Please retry later.`, - name: 'OwnerInFlightLimitError', + message: + 'Too many concurrent code executions. Please wait for some to complete before running more.', + name: 'Error', }, } } @@ -983,8 +986,8 @@ export async function executeInIsolatedVM( result: null, stdout: '', error: { - message: 'Distributed fairness is temporarily unavailable. Please retry.', - name: 'DistributedFairnessUnavailableError', + message: 'Code execution is temporarily unavailable. Please try again in a moment.', + name: 'Error', }, } }