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

[BUGFIX] Add check to ensure that setTimeout is not called with a value greater than MAX_SIGNED_INTEGER #1391

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

pdfowler
Copy link
Contributor

@pdfowler pdfowler commented Oct 20, 2021

Summary

In my local dev environment I've occasionally run into a scenario where my console gets flooded with TimeoutOverflowWarnings. I eventually traced the problem back to agenda's processJobs logic which would set the timeout for re-processing a future job without checking the bounds of the timeout value.

screen recording

Investigation

Unfortunately for us, the setTimeout method interprets values greather than 2e31-1 as a negative value, which is in turn interpreted as 1ms, causing a tight loop which will continue until the differen between "now" and nextRunAt is less than MAX_SIGNED_INTEGER.

Changes

  • Added a upper limit on the runIn interval calculation by adding a Math.min computation against MAX_SIGNED_INTEGER (2e31-1)
  • Opted to still set a timeout for MAX_SIGNED_INTEGER to ensure no weirdness in long-running servers

Keywords: TimeoutOverflowWarning

…ter than `2e31-1`

* `setTimeout` will interpret values greather than signed int max as `1`, causing a tight loop re-checking the jobProceessing for the job every 1ms
* Opted to still set a timeout for MAX_SIGNED_INTEGER to ensure no weirdness in long-running servers
@pdfowler pdfowler marked this pull request as ready for review October 20, 2021 22:50
@simllll
Copy link
Contributor

simllll commented Mar 18, 2022

This is already fixed in @hokify/agenda already since 2020 :-) see https://github.com/hokify/agenda/blob/1d75092b99c6128c2439921e95fe3171b0e5dec1/src/JobProcessor.ts#L457
you could try this fork instead

@pdfowler
Copy link
Contributor Author

Thanks @simllll, I've been looking at it recently and am debating my next move

@GorillaCoder
Copy link

GorillaCoder commented Jun 2, 2022

Problem with this fix is that it still calls setTimeout, for a time far outside the current processing period. If you have a whole bunch of jobs in this state, you will overload Node with work that will not run for at least 25 days. Imagine 10K or 100K+ jobs doing this. That is not an extreme load: 1 job/second * 3600 seconds/hour * 24 hours/day is 86400 jobs/day.

A better fix is to not process the job at all. Wait until the correct processing period to deal with it. This fix is simple, see #1453. Essentially,

diff --git a/lib/agenda/find-and-lock-next-job.ts b/lib/agenda/find-and-lock-next-job.ts
index 04c3ddc..98e85de 100644
--- a/lib/agenda/find-and-lock-next-job.ts
+++ b/lib/agenda/find-and-lock-next-job.ts
@@ -37,6 +37,7 @@ export const findAndLockNextJob = async function (
           },
           {
             lockedAt: { $lte: lockDeadline },
+            nextRunAt: { $lte: this._nextScanAt },
           },
         ],
       },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants