2

Update:
I just ran a simple script that prints new Date() with an interval of 1s.

setInterval(function(){
    console.log(new Date());
},1000)

After about 5-6 mins, it had skipped 1 second.
So looks like this might be because of how setInterval works internally.

Original Post:
Please note that I do not have a source code to simulate this, as my code original code contains huge amount of network and filesystem operations that I cannot put here.

I am setting multiple (500) setIntervals of 60 seconds. Each interval is set after approx 50 ms from each other

for(let i=1;i<500;i++){
    delayStart(i)
}

function delayStart(index){
    setTimeout(start,index*50)
}

function start(){
    setInterval(myOperations,60*1000)
}

myOperations consist of some TCP calls, synchronous file reads and asynchronous file writes. All of these operations are completed within 35 seconds, and the script is idle after that. As the event loop is not filled, I don't see a reason why the interval execution will get delayed.

My logs suggest that there is increase in the time when this starts.
The first execution started on the 10th second.

After 7 mins: 11th second
After 22 mins: 12th second
After 57 mins: 15th second
After 71 mins: 19th second

There was an increase of 9 seconds in 71 mins.
I know that might not seem a lot, but the operations I'm doing need to be done every minute.

Yes, I have thought of using database, and cron job. But I don't understand why this is causing the issue.

Dushyant Bangal
  • 6,048
  • 8
  • 48
  • 80
  • the timing coordination is pretty complicated when it comes to node.js. Because of single thread and preemption, we can't really expect the setTimeout to call a function at right time. `myOperations` can easily manipulate the order, depending on what it's executing. – kiddorails Jun 22 '18 at 11:42
  • But thats only when the single thread is busy. Like I said `myOperations` is getting everything done in 35 seconds. Theres nothing for 25 seconds. – Dushyant Bangal Jun 22 '18 at 11:47
  • Really good article i found [here](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/). It should answer your question – The Reason Jun 22 '18 at 12:14

1 Answers1

1

It's hard to know what's happening without all the source code, I understand that you can't provide it, but it is essential to the discussion.

When you call setTimeout (or setInterval) with a delay of X ms - it's important to know that it doesn't means that the callback will be called after X ms. Hard to grasp, but that true.

From MDN docs(it's about setTimeout, but also applied to setInterval):

Zero delay doesn't actually mean the call back will fire-off after zero milliseconds. Calling setTimeout with a delay of 0 (zero) milliseconds doesn't execute the callback function after the given interval.

So what does actually happen? The event loop has a queue of tasks(well, it might have more than one, but for the simplicity of the discussion, let's stick to one). When you call setTimeout/setInterval/promise those tasks adds up into the queue of tasks, if one task takes long time(ms scale) the other might get delayed.

My guess that your myOperations includes operations that will skew some the timeouts/intervals of your other tasks.

The solution? As you said, cron sounds like the way to go. Every operation will execute in a different process, hence, different event loop which will solve your problem.

EDIT AFTER YOUR UPDATE

What you see is the untrustedness of timers in js, might or might not be related to your original issue, depends on myOperations, it's hard to tell. More info here and here

Or Duan
  • 13,142
  • 6
  • 60
  • 65
  • You might've started typing before I added an update to the question. It is happening regardless of `myOperations`. I just wrote a script the prints date after each second. After 5-6 mins it had skipped a second. Now there is nothing else in the event loop, so it might be related to how `setInterval` works. I cannot go with crontab because I need to maintain some connections in memory. I might go with one of the npm packages. I didn't really notice this issue with one of those. – Dushyant Bangal Jun 22 '18 at 12:22
  • Updated with more info :) – Or Duan Jun 22 '18 at 12:26
  • I think it is related to my issue because all callbacks from`myOperations` are getting completed after 35s, so theres nothing in the event loop from my side except the next interval execution. – Dushyant Bangal Jun 22 '18 at 12:28