question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

queue.drain() invoked even when there are pending tasks

See original GitHub issue

What version of async are you using? 3.2.0

Which environment did the issue occur in (Node/browser/Babel/Typescript version) Babel. I used the async package, but the bug seems to exist in async-es as well.

What did you do? Please include a minimal reproducible case illustrating issue. push an empty array, and then array(s) with task, and then wait for queue to drain.

Here is a sample code:

import { queue } from "async-es";

const createTask = () => {
  return {
    doIt: () => {
      return new Promise((r) => setTimeout(r, 2000));
    }
  };
};

const createQueueAndProcess = async () => {
  const q = queue(async (task, callback) => {
    await task.doIt();
    console.log("task done");
    callback();
  });

  //Comment the empty array push line below
  // and see the issue go away
  q.push([]);
  q.push([createTask()]);

  await q.drain();
  console.log("all tasks completed");
};

createQueueAndProcess();

Code sandbox link: https://codesandbox.io/s/async-queue-issue-mqxo5

What did you expect to happen? Complete the one task that was pushed and then call drain. So the console will say

task done
all tasks completed

What was the actual result? drain is exited (event emitted) before the task getting completed.

all tasks completed
task done

If you remove that empty array, things get fixed. In real world, I got this issue when I was calling functions for getting tasks to upload any pending files to the server, and some of the functions returned empty arrays.

I did some digging around the internal/queue.js, and I think the issue is because of _maybeDrain and the setImmediate inside it. I understand the reason behind the code, but this is what is likely happening

  • pushed empty array
  • we are not doing anything, we should emit drain, schedule it.
  • actual things pushed. (setImmediate still have not emitted the drain)
  • this time we are not emitting coz we have actual work.
  • waiting for drain.
  • setImmediate now sees next tick, and calls the drain, which was supposed to be emitted long before.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:5
  • Comments:8

github_iconTop GitHub Comments

2reactions
aearlycommented, Jan 10, 2022
const q = queue(async (task, callback) => {

You error is here. You either use an async function, or a callback, not both at the same time. I’d recommend

const q = queue(async (task) => {

and simply returning when you need to.

1reaction
heartforitcommented, Oct 9, 2022

Hi,

just wanted to say, the patch fixes the problem very good. It´s in my eyes not an unwanted behavior, but I think it is a bug, since meantime changes on queue no evaluated correctly. Is this fixed anyhow?

Best

Read more comments on GitHub >

github_iconTop Results From Across the Web

Infinite execution of tasks for nodejs application - Stack Overflow
forEach(function (task) { queue.push(task); }); } //queue will call this whenever all pending work is completed //so wait 100ms and check ...
Read more >
How to solve Async queue process issues in Node.js
Queue.drain = function () { console.log('task is processed'); }; process1 function is the worker function that is called when a new task is ......
Read more >
Introducing Queues in Node.js | YLD Blog
js application talks to this unit using a serial port, and the wire protocol only accepts one pending command at a time. This...
Read more >
queue.rs.html -- source - Docs.rs
Source to the Rust file `src/task/queue.rs`. ... local queue. self.close_local(); // Release owned tasks self.shutdown_owned_tasks(); // Drain tasks pending ...
Read more >
better-queue - npm
Better Queue is designed to be simple to set up but still let you do ... drain event fires when there are no...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found