Queue with delayed jobs emits error when closing [BUG]
Created by: misos1
Description
In Queue.prototype.updateDelayTimer
in closure .then(nextTimestamp => {
is missing check whether is queue closing so it creates delayTimer
even when is queue already closing/closed which after 5 seconds throws connection error. When is queue closing it is clearing that timeout but mentioned closure is sometimes called after closing so it creates new timeout which is nowhere cleared.
Minimal, Working Test code to reproduce the issue.
This bug may not appear every run of this test code. Cluster is used to increase probability. On different systems may be needed to increase number of workers (try with 100, it does not must be number of cores) or to run this multiple times to reproduce.
let cluster = require("cluster");
let Queue = require("bull");
if(cluster.isMaster)
{
for(let i = 0; i < 10; i++) cluster.fork();
}
else
{
let queue = new Queue("queue");
queue.process(_job => console.log("started"));
queue.on("error", err => console.log("queue error:", err));
queue.add({}, { delay: 1000000 });
queue.close();
cluster.worker.disconnect(); // graceful shutdown
}
Possible output:
queue error: Error: Connection is closed.
at Redis.sendCommand (node_modules/ioredis/built/redis.js:552:24)
at Script.execute (node_modules/ioredis/built/script.js:23:34)
at Redis.updateDelaySet (node_modules/ioredis/built/commander.js:152:24)
at Object.updateDelaySet (node_modules/bull/lib/scripts.js:345:25)
at Queue.updateDelayTimer (node_modules/bull/lib/queue.js:819:6)
at Timeout._onTimeout (node_modules/bull/lib/queue.js:843:49)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7)
Bull version
3.10.0
Additional information
This change in bull/lib/queue.js
Queue.prototype.updateDelayTimer
seems fixes this bug:
.then(nextTimestamp => {
+ if(this.closing) return;
this.delayedTimestamp = nextTimestamp