Skip to content

Instantly share code, notes, and snippets.

@m5r
Last active March 25, 2022 06:20
Show Gist options
  • Save m5r/4c8177e340ab7e09993f5589ea0ef03a to your computer and use it in GitHub Desktop.
Save m5r/4c8177e340ab7e09993f5589ea0ef03a to your computer and use it in GitHub Desktop.
Node.js worker-based background jobs
import { Worker } from "worker_threads";
import path from "path";
import fs from "fs";
import { nanoid } from "nanoid";
type Handler<Job> = (job: Job) => Promise<void> | void;
export class BackgroundJob<Job> {
private static readonly workersDir = "/tmp/background-jobs";
private readonly workerPath: string;
constructor(handler: Handler<Job>) {
if (!fs.existsSync(BackgroundJob.workersDir)) {
fs.mkdirSync(BackgroundJob.workersDir);
}
const workerFilename = `${nanoid()}.js`;
this.workerPath = path.resolve(BackgroundJob.workersDir, workerFilename);
const code = `const { parentPort, workerData } = require("worker_threads");
parentPort.postMessage((${handler.toString()})(workerData));`;
fs.writeFileSync(this.workerPath, code, "utf8");
}
public async run(job: Job) {
const worker = new Worker(this.workerPath, { workerData: job });
worker.once("error", (error) => {
console.error(error);
});
}
}
import { BackgroundJob } from "~/background-job.server";
export default new BackgroundJob(({ number }: { number: number }) => {
const before = Date.now();
const result = fib(number);
console.log(`fib(${number}) = ${result}`);
console.log(`It took ${Date.now() - before}ms to run this job`);
function fib(num: number): number {
if (num <= 2) {
return 1;
}
return fib(num - 1) + fib(num - 2);
}
});
import type { LoaderFunction } from "remix";
import { useLoaderData, json } from "remix";
import fibonacciJob from "~/fibonacci-job";
export const loader: LoaderFunction = async () => {
const before = Date.now();
await fibonacciJob.run({ number: 38 });
return json({ took: Date.now() - before });
};
export default function Page() {
const { took } = useLoaderData();
return `It took ~${took}ms to queue the job. Look at the logs to see how long it took to run it in the background.`;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment