Cancellable Batch
Problem
You queue a batch of tasks into the worker pool and the user navigates away before they finish. Tasks that complete after teardown will try to update state that no longer exists — you need to cancel the entire batch.
Solution
Use AbortController to cancel queued tasks when the user navigates away:
ts
import { createWorker } from '@vielzeug/familiar';
const pool = createWorker<string, string>(
async (url) => {
const r = await fetch(url);
return r.text();
},
{ concurrency: 4, timeout: 8000 },
);
function startBatch(urls: string[]) {
const ac = new AbortController();
const promise = Promise.allSettled(
urls.map((url) =>
pool.run(url, { signal: ac.signal }).catch((err) => {
if (err instanceof DOMException && err.name === 'AbortError') {
console.log(`Batch cancelled: ${url}`);
return null;
}
console.error(`Failed to fetch ${url}:`, err);
throw err;
}),
),
);
return { result: promise, cancel: () => ac.abort() };
}
// Usage:
const batch = startBatch(['https://example.com/1', 'https://example.com/2']);
// User navigates away:
batch.cancel();
// Queued tasks will reject with AbortErrorPitfalls
- Aborting only cancels queued tasks. Tasks already dispatched to a worker slot continue executing — the
fetch()call inside the task is not aborted. Design task functions to check for stale results and discard them after abort. - The example creates
poolat module level but never disposes it. Callpool.dispose()orpool.close()at application shutdown to terminate worker threads and free resources.
Related
- Fibonacci with Pool and Timeout — stopping long-running tasks with a time budget
- React Integration — tying cancellation to component lifecycle