Last active
June 13, 2024 05:02
Node.js, very simple work queue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export type Task = () => Promise<void>; | |
export function addTask(doTask: Task) { | |
TASKS.push(doTask); | |
kickOffWorkers(MAX_WORKERS); | |
} | |
const TASKS: Task[] = []; | |
const workerPool: number[] = []; // "number" but really doesn't matter, this is just to keep track of how many parallel workers we already have | |
const MAX_WORKERS = 3; | |
function kickOffWorkers(numWorkers: number = MAX_WORKERS) { | |
const numCurrentWorkers = workerPool.length; | |
if (numCurrentWorkers < numWorkers) { | |
const takeTaskAndRecurse = async () => { | |
const task = TASKS.pop(); | |
if (!task) { | |
// delete | |
workerPool.splice(numCurrentWorkers, 1); | |
} else { | |
queueMicrotask(async () => { | |
await task(); | |
queueMicrotask(takeTaskAndRecurse); | |
}); | |
} | |
}; | |
queueMicrotask(takeTaskAndRecurse); | |
workerPool.push(Date.now()); // like I said, contents really don't matter | |
// try to fill the worker pool | |
kickOffWorkers(numWorkers); | |
} | |
} | |
// DEMO | |
(async function () { | |
const sleep = (milliseconds: number) => new Promise((resolve) => setTimeout(resolve, milliseconds)); | |
const sleepAndLog = (milliseconds: number, log: string) => | |
sleep(milliseconds).then(() => console.log(log, new Date())); | |
console.log(`${MAX_WORKERS} threads`); | |
console.log("_", new Date()); | |
addTask(async () => await sleepAndLog(1000, "1")); | |
addTask(async () => await sleepAndLog(1000, "2")); | |
addTask(async () => await sleepAndLog(1000, "3")); | |
await sleep(4000); | |
console.log("_", new Date()); | |
addTask(async () => await sleepAndLog(1000, "4")); | |
addTask(async () => await sleepAndLog(1000, "5")); | |
addTask(async () => await sleepAndLog(1000, "6")); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Output with MAX_THREADS going from 1 to 3: