Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Persist setTimeout and setInterval across Node.js restarts

I set quite a few server-side timeouts with setTimeout and setInterval for each connected user that can last for 10-30 seconds. If the Node.js instance restarts in the middle of one of these timeouts, they are obviously all cleared on restart, which can cause some issues for these users. How would I go about persisting these timeouts, or are there any modules that already help with this?

like image 580
James Simpson Avatar asked Jul 12 '12 14:07

James Simpson


People also ask

Does setTimeout repeat?

setTimeout allows us to run a function once after the interval of time. setInterval allows us to run a function repeatedly, starting after the interval of time, then repeating continuously at that interval.

Why is setTimeout returning a number?

Return value The returned timeoutID is a positive integer value which identifies the timer created by the call to setTimeout() . This value can be passed to clearTimeout() to cancel the timeout.

Should I use setInterval or setTimeout?

Usage notes. The setInterval() function is commonly used to set a delay for functions that are executed again and again, such as animations. You can cancel the interval using clearInterval() . If you wish to have your function called once after the specified delay, use setTimeout() .

Does setTimeout block Nodejs?

js setTimeout works. setTimeout is a non-blocking function which means that it does not block other functions in the call stack from executing. This means that the delay time specified is not a guarantee.


2 Answers

setTimeOut takes delay as parameter, so when setting timeout, capture currentServerTime + delay say serverTriggerTime and persist this in DB. Then, on restart of server, create the same timer using the serverTriggerTime. Then, delay = serverTriggerTime - currentServerTime, use this delay to set new timer.

When setting timer

const date = Date.now();
const serverTriggerTime = date + delay; // time in milliseconds

On server restart:

serverTriggerTime = // retrieve from DB.
newDelay = serverTriggerTime - Date.now();

Also, set new timer only if newDelay >= 0, meaning the trigger time has not reached and will happen after newDelay time.

like image 194
Sundeep Avatar answered Oct 20 '22 02:10

Sundeep


I would store the start times and durations in Redis and restart incomplete timers when your application reloads. Some Redis modules:

https://github.com/joyent/node/wiki/modules#wiki-db-nosql-redis

like image 24
Loc Nguyen Avatar answered Oct 20 '22 02:10

Loc Nguyen