| ; | |
| // Nodejs has a limit on timers of ~25 days. | |
| // Timers longer than this value need to be split into multiple | |
| // timeouts. | |
| // Parameters: | |
| // triggerTime: Date to fire the trigger (eg, from Date.now()) | |
| // keepAlive: true to keep the nodejs program alive until this timer fires | |
| // callback: The callback to fire at the given time | |
| // maxTimeout: (for testing) use a value other than node's max sleep time | |
| // for the individual sleep period | |
| // Note - this should be replaced with 'long-timeout' once it supports unref() | |
| function setLongTimeout(triggerTime, keepAlive, callback, maxTimeout) { | |
| var timeout = null; | |
| var TIMEOUT_MAX = maxTimeout || 2147483647; // 2^31-1 | |
| function doSleep() { | |
| var delay = triggerTime - Date.now(); | |
| // Cap timeout to Node's max setTimeout, see | |
| // <https://github.com/joyent/node/issues/8656>. | |
| if (delay > TIMEOUT_MAX) { | |
| delay = TIMEOUT_MAX; | |
| } | |
| // If we were called with a datetime of now or in the past | |
| if (delay <= 0) { | |
| callback(); | |
| return; | |
| } | |
| timeout = setTimeout(function () { | |
| timeout = null; | |
| // If teimer period is > ~25 days, we have to break into multiple | |
| // setTimeout's. See <https://github.com/joyent/node/issues/8656>. | |
| if (triggerTime && triggerTime > Date.now()) { | |
| doSleep(); | |
| } else { | |
| callback(); | |
| } | |
| }, delay); | |
| if (!keepAlive && typeof (timeout.unref) === 'function') { | |
| timeout.unref(); | |
| } | |
| } | |
| function clear() { | |
| if (timeout) { | |
| clearTimeout(timeout); | |
| } | |
| } | |
| doSleep(); | |
| return { clear: clear }; | |
| } | |
| module.exports = setLongTimeout; | |