Node.js: long delay - javascript

There is an event after which comes feedback on my server. I have to send a message to exactly one hour after the event.
I can use a setTimeout() but it seems it will not be good.
Perhaps it would be better if I start cron which will check the status of an event from database(such as every minute)
Does anyone know of a greater good option for the implementation of such a long delay?

If you require 100% reliability use a cron job. The problem with a cron job is that your code will be spread around the place and it would require configuration each time you set up a new server. An alternate approach would be to use an npm package like cron.
The issue with setTimeout() is that if your application crashes/restarts the future function call will be lost. However, each time your application starts, it could query the DB and see all missing timeouts and set them appropriately.

Related

Nodejs setInterval to repeat a task every 30s

I built a nodejs application that should execute several tasks.
My app.js has a function call to the manager module which controls those tasks.
I want to call that function from my app.js and perform those tasks every 30s.
something like:
setInterval(manager.tasks(), 30000);
My question is that if using setInterval could give me any performance problems (slowing down the computer, blocking resources or any other reason)
Is there a more efficient way to do this or is setInterval ok?
it depends on how heavy the work/processing you want to do is, setInterval is async so your code will only be run once every 30 seconds, but at the same time JavaScript is single-threaded, so if you're doing a lot of work in your task, the one time it runs in 30 seconds it may take too long to execute thus blocking resources.
In most cases you should be fine using setInterval, but if you really want to emulate multi-threading or if you're doing too much work in your task, you may want to spawn another child process https://nodejs.org/api/child_process.html process or use the new Worker Threads API https://nodejs.org/api/worker_threads.html instead, but keep in mind its not as simple to implement as a setInterval call
Use node-cron or node-schedule instead
setInterval is implemented in standard node js, you won't have any performance / blocking problems, most libraries also use setInterval
It completely depends on the function you executing inside setInterval. If it is I/O bound operation then you don't need to worry too much because libuv will handle itself But if it is CPU bound then I will suggest you to use child_process api to fork a new child process and do your stuff in to that.

Call NodeJs function at a specific moment in time

Is there a way to automate functions and call them at a specific mooment in time with Node.Js ? More precisely, I would like to create a reminder with node js. When I receive the date from the user, I have to send notification to remind him/her of something.
I know setTimeout() function but is it really good idea when I have large database of users ?
Thank you.
You can use setTimeout() and keep all the work inside your server, but for a large number of users, you would not necessarily want to set a timeout for every single user. All you really need is a single timeout for the next user that needs to be notified. When that timer fires, you then set a timer for the next user that needs to be notified and so on.
This can be done with an array of objects that you sort by the notification time. Each time you add something to the array, you cancel your current timer, add the new notification to the array, sort the array and set a timer for the earliest notification.
When a timer fires, you remove that item from the array and schedule the next one.
And, since you likely want this to survive a server restart, you save the notification array (probably in JSON format) to a file or to a database each time you modify it so you can reload that data upon a server restart.
FYI, there are scheduling modules for node.js that already offer this type of functionality if you'd prefer to pick up code someone else has already written.
Examples of some of these modules:
node-cron
agenda
node-schedule
What you are looking for is called a Scheduler or a cron job (its origin is from Linux OS).
In NodeJS you can find the node-schedule that implement the same idea.

Node.js to Socket.io Time Delay

I am working in real time trading application using Node.js(v0.12.4) and Socket.io(1.3.2). In that, I am facing some time delay nearly (100ms) when the response emitting from Node.js to GUI(Socket.Io).
I don't have a clue why the time delay is there while emitting data from Node.js to GUI (Socket.IO).
This happening in Production Site. And we tried to debug this in production server location also because of network latency. But same result.
Please anyone help me on this?
One huge thing to note before doing the following.
When calculating timing from back-end(server side) to front end
(client side) you need to run this on the same computer that uses the same
timing crystal.
quartz crystal-driven timing even on high quality motherboards deffer
from one another.
If you find no delay when calculating time delay from back-end(server side) to front end (client side) on the same pc then the delay you originally found was caused by either the network connection or the deference in the motherboards timing crystals. Which would eliminate Node.js and Socket.io as the cause of the time delay.
Basically you need to find out where the delay is happening before you can solve the problem.
What you need to do is find out what is causing the largest performance hit in your project. In order to do this you will need to isolate the time each process takes. You also need to measure the time delay from the initial retrieval of the data to the release of the data. Then measure the time delay of each function, method and process. Try to isolate the problem. You need to ask what is taking the most time to do?
In order to find out where your performance hit is coming from you need to do the following.
Find out how long it takes for your code to get the information it needs.
Find out how long each information manipulation process takes before it sends out the data i.e function/methods...
After the information is sent out find how long it takes to get the information to the client side and load.
Add all of the times up and make sure it is equal to your performance delay in order to insure you have all the data you require to isolate the performance leak.
Order every method, function, process… by its time delay most time consuming to least time consuming. When you find what processes are causing the largest delays you will then be able to fix the problem... Or at least explore tangible solutions...
Here are some tools you can use to measure the performance throughout your code.
First: Chrome has a really good tool that lets you see the performance of each piece of executed code.
https://developers.google.com/web/tools/chrome-devtools/profile/evaluate-performance/timeline-tool?hl=en
https://developer.chrome.com/devtools/docs/timeline
Second: performance-now node package. You can use it for dev performance testing.
Third: Stack overflow post on measuring time/performance in js.
Fourth: you can use things like console.time()
https://nodejs.org/api/console.html
https://developer.mozilla.org/en-US/docs/Web/API/Console/time
https://developer.chrome.com/devtools/docs/console-api
I have found out that time delay where it is happening.
Once, I have emitted the data from Client Socket to Node, I will show the some alert message ("Data Processed"). The alert message taking time to render in GUI.
This alert message blocking the response data from the Node to Socket.
Thanks for your help Guys.

Batch Backbone.js events?

My app's framework is built around collapsing backbone models sending the data via websockets and updating models on other clients with the data. My question is how should I batch these updates for times when an action triggers 5 changes in a row.
The syncing method is set up to update on any change but if I set 5 items at the same time I don't want it to fire 5 times in a row.
I was thinking I could do a setTimeout on any sync that gets cleared if something else tries to sync within a second of it. Does this seem like the best route or is there a better way to do this?
Thanks!
i haven't done this with backbone specifically, but i've done this kind of batching of commands in other distributed (client / server) apps in the past.
the gist of it is that you should start with a timeout and add a batch size for further optimization, if you see the need.
say you have a batch size of 10. what happens when you get 9 items stuffed into the batch and then the user just sits there and doesn't do anything else? the server would never get notified of the things the user wanted to do.
timeout generally works well to get small batches. but if you have an action that generates a large number of related commands you may want to batch all of the commands and send them all across as soon as they are ready instead of waiting for a timer. the time may fire in the middle of creating the commands and split things apart in a manner that causes problems, etc.
hope that helps.
Underscore.js, the utility library that Backbone.js uses, has several functions for throttling callbacks:
throttle makes a version of a function that will execute at most once every X milliseconds.
debounce makes a version of a function that will only execute if X milliseconds elapse since the last time it was called
after makes a version of a function that will execute only after it has been called X times.
So if you know there are 5 items that will be changed, you could register a callback like this:
// only call callback after 5 change events
collection.on("change", _.after(5, callback));
But more likely you don't, and you'll want to go with a timeout approach:
// only call callback 30 milliseconds after the last change event
collection.on("change", _.debounce(30, callback));

Browser timing out JavaScript recursive function, how to solve?

I had to develop a newsletter manager with JS + PHP + MYSQL and I would like to know a few things on browser timing out the JS functions. If I'm running a recursive function that delays a call to itself (while PHP returns a list of email), how can I be sure that the browser won't timeout this JS function ?
I'm asking this, because I remember using a similar newsletter manager, that while doing the ajax requests, after a few calls, it stopped without any apparent reason. I know JS is not meant for this, and I should use Crontab on server, but, I can't assume the users server handles cron, so I had to stick with JS + php.
PS - This didn't happened on this app yet, I'm just trying to prevent the worse of the scenarios (since I've tested a newsletter manager, that worked the same as this one I'm developing). Since my dummy email list is small and the delays between calls are also small, this works just fine, but let's imagine a 1,000 contact list, with a delay between sends of 120 seconds: Sending 30 emails for each 2 minutes.
By the way, why this ? Well, many hosting servers has a limit on emails sent per day or hour and this helps preventing violating that policy.
from the mootools standpoint, there are several possible solutions here.
request.periodical - http://mootools.net/docs/more/Request/Request.Periodical
has plenty of options that allow for handling batches of jobs, look at it like a more complex .periodical (setInterval) that understands async nature of the result and can compensate for lag etc. I think it can literally do what you set in your requirements out of the box, all you need is an oncomplete callback that clears up the done from your pending array (for eg).
request.queue - http://mootools.net/docs/more/Request/Request.Queue
basically, setup all your requests to handle the chunks of data and pass them on to Request.Queue to handle sequentially. Probably less sophisticated from the point of view of sending rate control.
How about a meta refresh. That will not cause a timeout in your javascript function. You Just reload your page after a specific time and then send the next emails out. Adding a parameter to the URL you can find out which "round" you are on.
Can this do the job for you?
You need to use setTimeOut. The code needs to yield control to the UI thread and let the browser become responsive to avoid the script from being stopped.
Read this post by Nick Z.
http://www.nczonline.net/blog/2009/01/13/speed-up-your-javascript-part-1/
There is also something the W3C Spec about this called "Efficient Script Yielding" I'm not sure how far along it is or if any browsers support it.
https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/setImmediate/Overview.html
You could also try HTML5 Web Workers.

Categories