Skip to content

Instantly share code, notes, and snippets.

@fasiha
Last active June 13, 2024 05:02
Show Gist options
  • Save fasiha/c04744393e0aafd07b0603593daacaa1 to your computer and use it in GitHub Desktop.
Save fasiha/c04744393e0aafd07b0603593daacaa1 to your computer and use it in GitHub Desktop.
Node.js, very simple work queue
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"));
})();
@fasiha
Copy link
Author

fasiha commented Jun 13, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment