From 7834aab1d062161dbcee13c77bf8f5b1694fb74d Mon Sep 17 00:00:00 2001 From: Devin Ivy Date: Mon, 20 Jul 2026 12:32:58 -0700 Subject: [PATCH] fix!: pinning a foreign pool handle throws instead of rebalancing --- src/worker-pool.ts | 3 ++- test/worker-handle.test.ts | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/worker-pool.ts b/src/worker-pool.ts index 24c23d0..ce54599 100644 --- a/src/worker-pool.ts +++ b/src/worker-pool.ts @@ -123,7 +123,8 @@ export function workers(sizeOrOpts?: number | WorkerOptions, opts?: WorkerOption function resolveWorker(task: Task): { worker: Worker; idx: number } { if (task.worker != null) { const idx = workerHandles.indexOf(task.worker); - if (idx !== -1) return { worker: pool[idx], idx }; + if (idx === -1) throw new Error('Task is pinned to a worker from another pool'); + return { worker: pool[idx], idx }; } const handle = balancer.select(workerHandles, task, balancerState); const idx = workerHandles.indexOf(handle); diff --git a/test/worker-handle.test.ts b/test/worker-handle.test.ts index 18e02d2..c17278b 100644 --- a/test/worker-handle.test.ts +++ b/test/worker-handle.test.ts @@ -62,4 +62,16 @@ describe('WorkerHandle', () => { run[Symbol.dispose](); await assert.rejects(() => run.workers[0].exec(identity(1)), { message: /disposed/ }); }); + + it('a task pinned to a foreign pool handle throws instead of silently rebalancing', async () => { + const runA = workers(1); + const runB = workers(1); + try { + const pinned = assign(runA.workers[0], identity(1)); + assert.throws(() => runB(pinned), { message: /pinned to a worker from another pool/ }); + } finally { + runA[Symbol.dispose](); + runB[Symbol.dispose](); + } + }); }); -- 2.51.2