Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Jobs don't complete after the sandboxed processors returns or throws an exception when using BUN #2536

Open
1 task done
alaimos opened this issue Apr 21, 2024 · 0 comments
Labels
bug Something isn't working

Comments

@alaimos
Copy link

alaimos commented Apr 21, 2024

Version

v5.7.4

Platform

NodeJS

What happened?

Hi,
I have a typescript application running through BUN that should perform some long jobs submitted by the user with BullMQ for job scheduling.
When I try to use the sandboxed processor, the job never reaches the completed state, although the processor code has finished and returned a value or thrown an exception.

The problem disappears if I remove any "await" statement from my processor code or the "async" from the function.

Furthermore, the producer code (file queue.ts in my example below) does not exit if I do not add "await queue.disconnect();" at the end.

I added all event handlers and didn't notice any errors, but the completed handler is never called, and the process remains stuck (no other jobs can be processed) until I close it manually with CTRL + C

How to reproduce.

In my code, I have a queue.ts file to submit test jobs:

import { Queue } from "bullmq";

const queue = new Queue("jobs", {
      connection: {
        host: (process.env.REDIS_HOST as string) ?? "localhost",
        port: parseInt((process.env.REDIS_PORT as string) ?? "6379"),
        username: process.env.REDIS_USER as string,
        password: process.env.REDIS_PASS as string,
      },
      defaultJobOptions: {
        attempts: 3,
        removeOnComplete: process.env.NODE_ENV !== "development",
        removeOnFail: process.env.NODE_ENV !== "development",
      }
});

export default queue;

await queue.add("job1", { name: "Job 1" });
await queue.add("job2", { name: "Job 2" });
await queue.add("job3", { name: "Job 3" });
await queue.disconnect(); // I had to manually disconnect otherwise this code will not exit

a worker.ts file to run the worker

import { Job, Worker } from "bullmq";
import path from "path";

const processorPath = path.join(__dirname, "processor.ts");

const worker = new Worker("job", processorPath, {
  connection: {
    host: (process.env.REDIS_HOST as string) ?? "localhost",
    port: parseInt((process.env.REDIS_PORT as string) ?? "6379"),
    username: process.env.REDIS_USER as string,
    password: process.env.REDIS_PASS as string,
  },
  autorun: true,
  skipStalledCheck: true,
  concurrency: 5,
});
worker.on("error", (error) => {
  console.error(error);
});
worker.on("active", (job, prev) => {
  console.log(`Job ${job.id} active from ${prev}`);
});
worker.on("completed", (job: Job, returnValue: any) => {
  console.log(`Job ${job.id} completed with return value: ${returnValue}`);
});
worker.on("failed", (job: Job | undefined, error: Error) => {
  console.error(`Job ${job?.id} failed with error: ${error}`);
});
worker.on("progress", (job: Job, progress: number | object) => {
  console.log(`Job ${job.id} is ${progress}% done`);
});

const gracefulShutdown = async (signal: string) => {
  console.log(`Received ${signal}, closing worker...`);
  await worker.close();
  process.exit(0);
};
process.on("SIGINT", () => gracefulShutdown("SIGINT"));
process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));

and a processor.ts file

import { SandboxedJob } from "bullmq";

export default async function processor(job: SandboxedJob) {
  job.log("Start processing job");
  await job.updateProgress(100);
  console.log("Doing something...", job.id);
  // sleep for 5 seconds
  await new Promise((resolve) => setTimeout(resolve, 5000));
  return "Job completed!";
}

I run the script using bun queue.tsand bun worker.ts in two shells.

Relevant log output

> bun worker.ts
Job 178 active from waiting
Job 179 active from waiting
Job 180 active from waiting
Job 179 is 100% done
Job 180 is 100% done
Job 178 is 100% done
 <-------------- The completed handler never executes, and the code does not exit until I close it manually with CTRL + C

Code of Conduct

  • I agree to follow this project's Code of Conduct
@alaimos alaimos added the bug Something isn't working label Apr 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant