diff --git a/lib/commands/cleanJobsInSet-3.lua b/lib/commands/cleanJobsInSet-3.lua index 830105946..a8298d1a1 100644 --- a/lib/commands/cleanJobsInSet-3.lua +++ b/lib/commands/cleanJobsInSet-3.lua @@ -53,7 +53,8 @@ local jobTS -- - Once, if limit is -1 or 0 -- - As many times as needed if limit is positive while ((limit <= 0 or deletedCount < limit) and next(jobIds, nil) ~= nil) do - for _, jobId in ipairs(jobIds) do + local jobIdsLen = #jobIds + for i, jobId in ipairs(jobIds) do if limit > 0 and deletedCount >= limit then break end @@ -73,7 +74,10 @@ while ((limit <= 0 or deletedCount < limit) and next(jobIds, nil) ~= nil) do end if (not jobTS or jobTS < maxTimestamp) then if isList then - rcall("LREM", setKey, 0, jobId) + -- Job ids can't be the empty string. Use the empty string as a + -- deletion marker. The actual deletion will occur at the end of the + -- script. + rcall("LSET", setKey, rangeEnd - jobIdsLen + i, "") else rcall("ZREM", setKey, jobId) end @@ -111,4 +115,8 @@ while ((limit <= 0 or deletedCount < limit) and next(jobIds, nil) ~= nil) do end end +if isList then + rcall("LREM", setKey, 0, "") +end + return deleted diff --git a/test/test_queue.js b/test/test_queue.js index 4b50194c4..0706515f8 100644 --- a/test/test_queue.js +++ b/test/test_queue.js @@ -3008,6 +3008,16 @@ describe('Queue', () => { }); }); + it('should succeed when the limit is higher than the actual number of jobs', async () => { + await queue.add({ some: 'data' }); + await queue.add({ some: 'data' }); + await delay(100); + const deletedJobs = await queue.clean(0, 'wait', 100); + expect(deletedJobs).to.have.length(2); + const remainingJobsCount = await queue.count(); + expect(remainingJobsCount).to.be.eql(0); + }); + it("should clean the number of jobs requested even if first jobs timestamp doesn't match", async () => { // This job shouldn't get deleted due to the 5000 grace await queue.add({ some: 'data' });