Im building a node.js script/app/process (new to node and its definitions) that should run at a certain hour (from a conf file) every day.
Im using the Node Schedule package to schedule the main function to run at that appointed time everyday. But the thing is this package does an "in-process scheduling", which means my script must keep running in the background for the scheduling to work.
So basically my code should look like this at the end:
global consts initializing and dependencies (requires)
job scheduling
defining all functions necessary
logic to make script run permanently.
This node.js app runs inside a docker on an ec2 machine in AWS.
How can I accomplish the task of running it permanently? I need a programatic solution, something (a package, a design pattern) I can embed inside my code.
Might be important to note that inside my code I have only a few lines of "requires" and const initializations, and then 1 main function that invokes everything else, if it helps somehow. Also, because im using that Node Scheduler I mentioned, restarting the script when it ends (for example through docker if its possible) is a bad idea, because the scheduling job would be lost and the script itself does nothing except initializations and scheduling the main function to the desired time, so it would restart possibly every few milliseconds, which I guess is a bad practice.
Well, someone in the comment section pointed me to my mistake... I saw the following paragraph on node-scheduler and didn't even test if it works without tryin to find a way to "run forever":
"Note that Node Schedule is designed for in-process scheduling, i.e. scheduled jobs will only fire as long as your script is running, and the schedule will disappear when execution completes. If you need to schedule jobs that will persist even when your script isn't running, consider using actual cron."
But apparently they meant I should keep the process running, effectively means the scheduler will terminate if I close the terminal. Here is a topic with a question and answer about how to prevent that from happening, if someone needs a reference:
How to make a node.js application run permanently?
Thanks to all who tried to help :)
Related
I'm new to Java, but not so to JavaScript.
So, in JS you can't use code like this
while(true){/* do something */}
Because this way browser tab will just get stuck forever. Actually it will be hard to close this tab after infinite loop was invoked.
But in Java, as I saw, it is normal to use code like this
try {
while (true) {
try {
socket.println(data);
} finally {
socket.close();
}
}
} catch (IOException exception){
log(exception);
}
Q1. So, I'm wondering how infinite loop works in Java?
Q2. If I want to listen socket for data for hours, does my Thread will get stuck as browser tab with JavaScript?
Q3. (if Q2 == false) Why Java infinite loop don't consume all of the available resources of Thread as we see in JavaScript?
Q4. Whether this variant of code is more appropriate for socket reading or not because I can miss some important data while "sleeping"?
while(true){
readSocket();
Thread.sleep(10);
}
Q1 - An infinite loop will repeat the code until interrupted somehow. In this case, it's actually not infinite - it uses a trick of a kind. It exists the loop when an exception in thrown.
Q2 - The thread does indeed get stuck in the loop. But in Java (and many other languages) you can just create another thread to run your UI or whatever you need to run at the same time.
Q3 - No, it uses the thread fully.
Q4 - Sleeping will not help you. When the thread is sleeping it just doesn't do anything, so it remains 'stuck'.
Q1) First to understand why this code is not an infinite loop, look at how exceptions work in java. Whenever an exception happens in a try block, it immediately moves to the catch statement. Thus, the socket will eventually close and then an exception will be thrown when the socket is accessed again. The while loop will be exited and the error handler block will run. So this is not an infinite loop.
Infinite loops in java work like any other programming language - if you don't have an exit condition, the code will simply not exit.
Q2) If you want to listen for data for a long period of time, there are a number of pre-built classes that handle this stuff for you. Look into Java ServerSocket and a number of related / derivative classes.
Q3) Not sure how to answer this, see above.
Q4) Again, see answer #2. A lot of these problems are solved by using the builtin server methods. If you don't want to use builtins, they serve as a good reference for building your own classes.
Good luck!
AFAIK the brower use a single thread for both:
UI rendering
JS execution
So it explained why browser stuck (I guess you mean the UI get stuck) when there is a infinity loop in the JS execution. For detail Checkout this post
As for Java, most UI program are multi-threaded,
GUI program. The update of UI is in another thread, so the GUI won't stuck when another thread is stuck.
Web Server. Most java webserver will spawn a new thread (or use a thread pool) when handling incoming request, thus the accept loop won't stuck.
Further you may want to checkout the underlaying browser execution model: Event Loop
Maybe it seems an odd question... but I don´t know exactly how to program a task... o rather, I don´t know exactly wich one is the best solution. I just finish a web app and it needs everyweeks, every monday, execute a "special" piece of code, that it can´t be invoked from anywhere else.
The cron solution looks much better, but the piece of code would be isolated, like if this code and the rest of the application were two diferents programs. And the worst handicap of the cron solution (even tough I suposse it can be solved), when I call the javascript file from the cli node cron.js it makes good its job, but it never ends... this is normal?? or it depends about the code?? Becouse I don´t want to execute one instance, and the next week, with the first instance still running, run the second, and everyweeks the same problem.
The "setInteval" solution could be setting the time for a day, and testing if it is monday (on monday makes the action)... or maybe setting the time for a week (604800000 miliseconds)... This solution hasn´t these problems, especially the last, but it consumes a lot of resources (I think...no?).
What is the best solution?? Any different?? And if the cron is the best... how to stop the task? (uuuuuhhhh maybe other programed task with cron -a shell- one minute after to kill the node task... uuummm a little botched job).
Thank you very much.
I am playing with the Node.JS library provided by Amazon to manage the EC2 and Autosclaing group. I have written a program to delete an instance so that the autoscaling group will create a new instance. But before I delete any additional instances, I need to make sure that the new one is generated by amazon and is running. For that I need to pause my program and keep checking till I get a positive response. So this is how it works ---
(I usually have 3-4 instances and have to replace with 3-4 instances of new type.)
So my program is --
updateServer(){
Which has the code to retrieve the instances from the server.
foreach(instance in the list of instances){
replace(); (with new one.)
}
}
replace() {
delete the old one.
while(new instance is not generated) {
check();
}
}
check(){
return the status.
}
Now the question is I need this to happen in sequence. How can I pause the program?
Because in my case, the foreach loop executes and the program ends and it does not enter that check loop. Can you please give me ideas.
Thanks
Links -- http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/frames.html
The problem you are describing here is one one 'polling' and while talking of 'pauses' is normally an anti-pattern in node's asynchronous programming model, polling is possibly the one case where it has valid application.
However for reasons of code maintainability - in this case the ability to add other tasks later (such as other checks), you should also handle the polling asynchronously.
Here are some different approaches that should solve your problem.
1. Don't handle the problem in node.js at all - invoke the node application from the host's crontab and design the program to exit. This isn't very node-ish though but its certainly robust solution.
2. Use npm to install the node timer module [https://github.com/markussieber/timer]. Using timer you would pass check() function as an argument so it would call it back periodically. This is more slippery but scales in that you can have lots of checks running which for a scaleable EC2 deployment is what is probably called for.
timer = require('timer'); //import the time module
function check(){ //check function now polls
//add an if(something==true) statement here to allow you to exit if necessary
console.log("Checking stuff");
timer.timer(200, check); //calls this function repeatedly every 200ms
}
check(); //starts the code polling
3. Having said that, the functionality you are trying to implement sounds to me like it is the same as that provide by Amazon Autoscaling [http://aws.amazon.com/autoscaling/] and Amazon Elastic Beanstalk [http://aws.amazon.com/elasticbeanstalk/]. You might also have some luck with those.
Happy node hacking :)
nodejs isn't made to pause, really. you might be looking for something like an eventEmitter, so you can call a function when you emit an event. http://nodejs.org/api/events.html
You should never pause in node. Take a look at async (https://github.com/caolan/async). What you need is probably async.forEachSeries(), which allows you to do things in series, but asyncronously.
In your case it would start up a server and when that is started a callback is called that makes the series continue on the next server etc.
Here's some sample code from node-levelup https://github.com/rvagg/node-levelup/blob/master/test/benchmarks/index.js#L60-L84
I am willing to implement some server side code using node.js.
Does node.js (js) have any synchronization inbuilt.Like we have
synchronized key word in java?
Can i make some code block synchornized?so that at one time only on thread can execute it?
In Node, every code block is synchronized. Node uses cooperative multitasking; the only time another piece of code can run is when the first piece of code returns.
That's the driving force behind its event-driven design: you ask for something slow to be done for you (e.g. reading from a file), and then you specify another function to be run when that slow operation is done. The first function returns, and Node can run other functions while it's waiting for the I/O operation to be done. When the I/O is ready, and all other functions are done running, then your continuation will be called.
Synchronization isn't needed when you're in full control of when your code will yield. In effect, every function is synchronized.
Node does not use threads. It is based on an event machine...
So I think your question is a little off.. Maybe if you give a problem that you are trying to solve people here can guide you.
Yes You can do it with fibers, more details here http://alexeypetrushin.github.com/synchronize
In my specific case, at least. Not trying to make general statements here.
I've got this web crawler that I wrote in Node.js. I'd love to use Ruby instead, so I re-wrote it in EventMachine. Since the original was in CoffeeScript, it was actually surprisingly easy, and the code is very much the same, except that in EventMachine I can actually trap and recover from exceptions (since I'm using fibers).
The problem is that tests that run in under 20 seconds on the Node.js code take up to and over 5 minutes on EventMachine. When I watch the connection count it almost looks like they are not even running in parallel (they queue up into the hundreds, then very slowly work their way down), though logging shows that the code points are hit in parallel.
I realize that without code you can't really know what exactly is going on, but I was just wondering if there is some kind of underlying difference and I should give up, or if they really should be able to run about as fast (a small slowdown is fine) and I should keep trying to figure out what the issue is.
I did the following, but it didn't really seem to have any effect:
puts "Running with ulimit: " + EM.set_descriptor_table_size(60000).to_s
EM.set_effective_user('nobody')
EM.kqueue
Oh, and I'm very sure that I don't have any blocking calls in EventMachine. I've combed through every line about 10 times looking for anything that could be blocking. All my network calls are EM::HttpRequest.
The problem is that tests that run in under 20 seconds on the Node.js code take up to and over 5 minutes on EventMachine. When I watch the connection count it almost looks like they are not even running in parallel (they queue up into the hundreds, then very slowly work their way down), though logging shows that the code points are hit in parallel.
If they're not running in parallel then it's not asynchronous. So you're blocking.
Basically you need to figure out what blocking IO call you've made in the standard Ruby library and remove that and replace it with an EventMachine non blocking IO call.
Your code may not have any blocking calls but are you using 3rd party code that is not your own or not from EM ? They may block. Even something as simple as a debug print / log can block.
All my network calls are EM::HttpRequest.
What about file IO, what about TCP ? What about anything else that can block. What about 3rd party libraries.
We really need to see some code here. Either to identify a bottle neck in your code or a blocking call.
node.js should not be more than an order of magnitude faster then EM.