nodejs multiple timers and cpu usage - javascript

Let's say I have 1000 concurrent socket.io connections.
On disconnect, I would like to give at least 30 seconds for the user to re-connect and maintain its session, so I thought of adding a timer to do that.
Would that be cpu intensive considering the timers would run for 30 seconds and only execute simple database queries? This is backend btw, so no browser.
Thanks

Would that be cpu intensive considering the timers would run for 30 seconds and only execute simple database queries?
You don't want a timer to run every 30 seconds and run database queries when there's no disconnected sockets. That's kind of like "polling" which is rarely the most efficient way of doing things.
What would make more sense is to set a 30 second timer each time you get a socket disconnect. Put the timerID in the session object. If the user reconnects, upon that reconnect, you will find the session and find a timerID in there. Cancel that timer. If the user does not reconnect within 30 seconds, then the timer will fire and you can clear the session.
Timers themselves don't consume CPU so it's no big deal to have a bunch of them. The node.js timer system is very efficient. It keeps track of when the next timer should fire and that is the only one that is technically active and set for a system timer. When that timer fires, it sets a system timer for the next timer that should fire. Timers are kept in a sorted data structure to make this easy for node.js.
So, the only CPU to be consumed here is a very tiny amount of housekeeping to organize a new timer and then whatever code you're going to run when the timer fires. If you were going to run that code anyway and it's just a matter of whether you run it now or 30 seconds from now, then it doesn't make any difference to your CPU usage when you run it. It will consume the same amount of total CPU either way.
So, if you want to set a 30 second timer when each socket disconnects, that's a perfectly fine thing to do and it should not be a noticeable impact on your CPU usage at all.
Here's a reference article that will help explain: How does Node.js manage timers internally and also this other answer: How many concurrent setTimeouts before performance issues?

Related

Idle games and web workers for background tabs

I've been working on an idle/incremental game in my free time.
The main game loop function gets called many times a second using setInterval.
Since chrome (and probably other browsers) throttle function calls to 1 per second, my game loop doesn't properly update the right amount of times so now im looking into web workers.
After reading through the WebWorkers documentation on MDN, i still have a question on how to properly implement the web worker.
My current idea is to detect when the user swaps tabs (onblur):
Pause the setInterval for gameLoop
Post a message to my worker with the current game state
Within the worker, continue computing the game state
When tab gets refocused, send message back and update game state with message
unpause setInterval and terminate worker.
Would this be the right way to use the Web Worker?
Thanks!
-EDIT-
Some additional info, my game is an idle game similar to cookie clicker so there isnt any position tracking.
A very brief idea of something that is within my gameLoop is a function call to gainResources(resourcePerSecond/gameTickRate).
My solution to stopping background tabs from throttling is to calculate the difference in time between each loop, and use that value to calculate how much things should've changed, assuming your loop updates things like resource amounts.
Example -
function loop() {
let now = Date.now();
let diff = now - Game.lastUpdate;
Game.lastUpdate = now;
// diff is now the exact amount of ms since loop has been called.
}
This way you are also sure to give an accurate production rate as setInterval doesn't call functions at exactly the same interval every time.

Does setTimeout function affect the performance of Node.js application?

I have a request handler for ticket booking:
route.post('/makeBooking', (req, res) => {
// Booking code
setTimeout(function () {
// Checks if the payment is made, if not then cancels the booking
}, 900000);
});
Now I've a route which makes a booking and if the payment is not made within 15 minutes the timeout function will cancel the booking.
Will this function cause any performance related issues or memory leaks?
Will this function cause any performance related issues ...
No it won't, at least not in and by itself. While setTimeout is waiting to invoke it's callback, it's non-blocking. The call is simply added to a queue. At some point in the future the callback fires and the call is removed from that queue.
In the meantime, you can still process stuff.
... or memory leaks?
The setTimeout callback is within a closure. As soon as setTimeout invokes the callback, it becomes eligible for garbage collection.
Unless you get many millions of bookings within the 900000ms timeframe, you have nothing to worry about; the number of course depends on the memory
size you allocated to your Node.js application.
Of course if you do get that many requests-per-second, you have other, more important stuff to worry about.
It won't have performance issues or memory leak problems, but using a 15 minutes timeout function might be problematic for debugging and maintaining.
Especially something like cancelling a booking should be solved another way.
You always should write your node application in a way that:
You can run it in cluster mode (Even if you don't need it for performance reasons)
That a crash of the application and immediate restart would not cause much information loss (a 15 minute timeout could be problematic here)
That a crash or restart of the application will not result in an inconsistent state (e.g. a pending booking that would not be cancelled anymore)
So assuming that you already use a database for the booking process, then you should also do the 15 minute timing within the database.

NodeJS - Multiple Timeouts vs one Interval for sessions in bots

I would like the messenger bot to notify the user that their session ended if they did not write/give input to the bot for some time. In order to do so, I first thought about using setTimeout() for each user which will reset upon activity. But that means if there will be 100 active users, there will be 100 Timeouts at the same time.
I wanted to know, if having one Interval instead that checks through each user`s session end timestamp every 30-60 seconds a better approach? The active users are stored in memory.
setTimeout is more precise in your case: each session will be ended independently and closer to the time it was supposed to end. It will also spread the activity more evenly. Since JS is single-threaded, the timeouts will not fire in parallel, even though there will be hundreds of them at the same time.
setInterval will create spikes of activity every 30-60 seconds, and will sometimes let the sessions stay alive longer than they should.
As per the cost of multiple timeouts running at the same time, please see this answer.

How to Long Poll in NodeJS / Javascript?

Just to be clear my understanding of long polling is that you make request to a server on a time interval.
I am trying to implement a bitcoin purchasing system that checks the blockchain for change in my wallets balance. I know there are websockets that do this but I have to wait for 1 confirmation to receive an update and the REST API offers more flexibility, so I would just prefer to make a request to the server every 5 seconds or so and check each response for a change in my balance then go from there.
The issue is I can't seem to figure out how to do this in NodeJS. Functionially this is how I imagine my code.
Get current balance (make request)
Get current balance again (make request)
Check if there is a difference
**If not**
wait 5 seconds
Get current balance
Check for difference
repeat till different (or till timeout or something)
If different
do some functions and stop checking balance.
I've been trying to do each step but I've gotten stuck at figuring out how to create a loop of checking the balance, and stopping the loop if it changes.
My original thought was to use promises and some for loops but that doesn't materialize.
So now I am asking for your help, how should I go about this?
One way to do this would be to setup a setInterval timer to kickoff a request every x seconds. By setting some logic after the response you can then choose to de-reference the timer and trigger another function. Here's a snippet. You'll notice I set a variable to reference the timer, and then de-reference it by setting it to null, where then the GC is smart enough to release. You may also use the 'clearTimeout' function, which is perhaps the better way to go.

Reducing Javascript CPU Usage

I'm planning on writing some code for encrypting files in javascript locally. For large files and large key sizes, the CPU usage (naturally) is pretty high. In a single script design, this often hangs the browser until the task is complete.
In order to improve responsiveness and allow users to do other things in the mean time I want to try make the script 'friendlier' to the user's PC. The encryption process will be reading a file as a binary string and then encrypting the string in chunks (something like 1KB/chunk - needs testing). I want to try and user HTML5-based workers to make the whole thing as incremental as possible. Something like:
Spawn worker
Send worker a binary data chunk
Worker completes encryption, passes back new chunk
Worker dies.
This might also help with multicore processors, by having multiple workers alive at once.
Anyway, has anybody looked at deliberately slowing down a script in order to reduce CPU usage? Something like splitting the worker's encryption task into single operations, and introducing a delay between them.
Interval timer callback every 100ms (example).
Is worker busy?
Yes - Wait for another interval
No - Start encrypting the next letter
Advice/thoughts?
Does anyone have experience using workers? If you seperate the main UI from intensieve work by making it a worker, does the responsiveness increase?
This doesn't utilize anything HTML5, but here's an example for calling a function every N milliseconds, assuming you can determine an appropriate wait time. Basically, I'm trying to help you by showing you a way to enforce stalling some amount of time before doing more processing.
function doSomething(){
clearTimeout(timeout);
// do your "expensive" processing
// ...
// decide the job is done and return here or else
// call doSomething again in sleepMS milliseconds
timeout = setTimeout(doSomething,sleepMS);
}
var timeout;
var sleepMS = 1000;
doSomething();
EDIT
changed last line from
var timeout = setTimeout(doSomething,1000);
to just this
doSomething()
EDIT 2
Changed 1000 to sleepMS in setTimeout call, duh :)

Categories