bullmq icon indicating copy to clipboard operation
bullmq copied to clipboard

fix(queue-getters): filter undefined jobs from getJobs

Open DanFaudemer opened this issue 10 months ago • 3 comments

Ensure getJobs does not return undefined if a job is deleted between ID retrieval and fetching.

Why

  • getJobs could return undefined if a job was deleted between ID retrieval with a return type Promise<JobBase[]>
  • This caused unexpected behavior when processing job lists.
  • Fixing this ensures getJobs only returns valid job objects.

How

  • Updated getJobs to filter out undefined results.
  • Ensured that the function always returns a valid JobBase[] array.

DanFaudemer avatar Jan 29 '25 10:01 DanFaudemer

Thanks for the PR. There is a subtle issue here and that is that the number of returned jobs will not match the requested amount based on the start and end arguments, which for an application that maybe is doing pagination it could lead to believe that there are no more pages left as the last call returned less jobs than expected. Maybe the best solution would be to perform the whole operation using MULTI in one transaction.

manast avatar Jan 30 '25 09:01 manast

You are right! Just for reference, the Python version is already filtering out None jobs: Python BullMQ - Queue.

I don’t know the codebase in-depth, but I believe that as soon as a job is missing, pagination will break—even without explicitly filtering out missing jobs—because job IDs will shift.

I see three possible solutions:

  • I am not a redis expert but as you mentioned we may use MULTI with WATCH on getRanges and have a retry mechanism in case jobs have been updated
  • Fetch additional pages until the result contains the expected number of jobs
  • Modify the return type of getJobs to include undefined jobs

Which solution do you think is the best approach?

DanFaudemer avatar Jan 31 '25 20:01 DanFaudemer

Yeah, MULTI will not work in this case actually, because you need to have the job ids before you can actually fetch the jobs themselves, so the only way to do this properly would be with a small lua script that both gets the job ids and then fetches the jobs themselves and returns them in one array.

manast avatar Feb 03 '25 09:02 manast