restart node.js application on file change - node.js

as you know in node.js if you edit a server-side file, you need to restart the application in order to make for the changes.
Now I was wondering is there a way to do this inside the server, as we know when a file has changed or not(based on last modification date), we only need to re-run the application or restart it or do something that make the changes available without us doing it from the command line.
And we all know how to do this with some Grunt.js(or something like that) or supervisor, but I want to do this without any external package.
thanks alot :)

You can initially have the server startup such that when it ends it start again. In a Bash file it would simply be a recursive function.
function start(){
node index.js
start
}
Or in a batch file a goto statement
:start
node index.js
goto start
Then in your node server when you detect a file change you simply end the process
For watching the files there's modules out there that make it easier. Eg. watch
require('watch').watchTree('./server', process.exit);

You can maybe use this method to watch the files who have to restart server on change :
https://nodejs.org/api/fs.html#fs_fs_watchfile_filename_options_listener

Using cluster.fork to run all code in a child process and setting the master process to fork a new child whenever the previous child exits. Then simply exit the child focibly upon file change, using chokidar.
// Put this at the very beginning of your code
var cluster = require('cluster');
if (cluster.isMaster) {
cluster.on('exit', cluster.fork);
cluster.fork();
return;
}
require('chokidar').watch('./**/*.*').on('change', process.exit);
// Rest of the code here
...

Related

Close another process from node on Windows

How can I kill a process from node on Windows?
I'm making a updater. It needs close a windows executable (.exe) to download the updates. (The update process is download and overwrite). I read that this is possible with process.kill(pid[, signal])
But, How can I get the PID of the process if I know the name of the process?
According to the documentation, you simply access the property.
process.kill(process.pid, 'SIGKILL');
This is a theoretical, untested, psuedo function that may help explain what I have in mind
exec('tasklist', (err, out, code) => { //tasklist is windows, but run command to get proccesses
const id = processIdFromTaskList(processName, out); //get process id from name and parse from output of executed command
process.kill(id, "SIGKILL"); //rekt
});
Use node-windows to get pid of process you want to kill so that you can call process.kill. The library also provides an api to kill task.

Execute node command from UI

I am not very much familiar with nodejs but, I need some guidance in my task. Any help would be appreciated.
I have nodejs file which runs from command line.
filename arguments and that do some operation whatever arguments I have passed.
Now, I have html page and different options to select different operation. Based on selection, I can pass my parameters to any file. that can be any local node js file which calls my another nodejs file internally. Is that possible ? I am not sure about what would be my approach !
I always have to run different command from terminal to execute different task. so, my goal is to reduce that overhead. I can select options from UI and do operations through nodejs file.
I was bored so I decided to try to answer this even though I'm not totally sure it's what you're asking. If you mean you just need to run a node script from a node web app and you normally run that script from the terminal, just require your script and run it programmatically.
Let's pretend this script you run looks like this:
// myscript.js
var task = process.argv[2];
if (!task) {
console.log('Please provide a task.');
return;
}
switch (task.toLowerCase()) {
case 'task1':
console.log('Performed Task 1');
break;
case 'task2':
console.log('Performed Task 2');
break;
default:
console.log('Unrecognized task.');
break;
}
With that you'd normally do something like:
$ node myscript task1
Instead you could modify the script to look like this:
// Define our task logic as functions attached to exports.
// This allows our script to be required by other node apps.
exports.task1 = function () {
console.log('Performed Task 1');
};
exports.task2 = function () {
console.log('Performed Task 2');
};
// If process.argv has more than 2 items then we know
// this is running from the terminal and the third item
// is the task we want to run :)
if (process.argv.length > 2) {
var task = process.argv[2];
if (!task) {
console.error('Please provide a task.');
return;
}
// Check the 3rd command line argument. If it matches a
// task name, invoke the related task function.
if (exports.hasOwnProperty(task)) {
exports[task]();
} else {
console.error('Unrecognized task.');
}
}
Now you can run it from the terminal the same way:
$ node myscript task1
Or you can require it from an application, including a web application:
// app.js
var taskScript = require('./myscript.js');
taskScript.task1();
taskScript.task2();
Click the animated gif for a larger smoother version. Just remember that if a user invokes your task script from your web app via a button or something, the script will be running on the web server and not the user's local machine. That should be obvious but I thought I'd remind you anyway :)
EDIT
I already did the video so I'm not going to redo it, but I just discovered module.parent. The parent property is only populated if your script was loaded from another script via require. This is a better way to test if your script is being run directly from the terminal or not. The way I did it might have problems if you pass an argument in when you start your app.js file, such as --debug. It would try to run a task called "--debug" and then print out "Unrecognized task." to the console when you start your app.
I suggest changing this:
if (process.argv.length > 2) {
To this:
if (!module.parent) {
Reference: Can I know, in node.js, if my script is being run directly or being loaded by another script?

How to load data from database when the node server start

I want to load some data from database to cache when the node server start,but I am not sure how to implement it:
I have though this:
load.js:
var connection=require('mysql');
var loader=function(){
connection.query('sql',function(err,rows){
cache.put('data',rows);
});
};
loader();
module.exports={}; //export nothing
Then I have two questions:
1 Is this the node way to do the job?
2 The load process is async, which means once the file is loaded(by the require command), the load job may not be completed. I need something like the servlet initialization work in JavaEE. The server will start only after the job done.
Is this possible?
Here's how to perform initialization tasks in node
app.js
var project = require('project'); // assuming project.js contains your project code
function initializationTasks(callback){
// perform all initialization tasks e.g. read from database
callback();
}
initializationTasks(project.start); // start executing your project

How to keep Node uv_run from exiting when hosting own thread in an add on?

I have a custom server that runs in its own posix thread in a native Node Add On.
What is the proper way to keep the node process running the uv_run event loop? In other words, if I start the server in my Add On via a script, my process will exit at the end of the script instead of keeping the event loop running.
I've tried adding a SignalWatcher via process.on and that still exits. I didn't see anything else in the process object for doing this from script.
In node.cc, there is this comment:
// Create all the objects, load modules, do everything.
// so your next reading stop should be node::Load()!
Load(process_l);
// All our arguments are loaded. We've evaluated all of the scripts. We
// might even have created TCP servers. Now we enter the main eventloop. If
// there are no watchers on the loop (except for the ones that were
// uv_unref'd) then this function exits. As long as there are active
// watchers, it blocks.
uv_run(uv_default_loop());
EmitExit(process_l);
What does the Add On have to do?
I've tried calling uv_ref(uv_default_loop()) in the main thread in my Add On when starting the server/pthread but the process still exits.
Note: I can bind to a TCP/UDP port or set a timer and that will keep uv_run from exiting, but I would like to do this the "correct" way.

Using forever with Node.js

I have a few, possibly trivial, questions with using forever with Node.js. From what I have read, forever can be used programatically and it maintains a list with all the scripts that use forever. When that process dies, it automatically spawns a new one until it is stopped.
However, my question is, how does forever do this? Does it add these scripts to be started on boot as well?
You can use forever programatically like this:
Using an instance of Forever inside a node.js script:
var forever = require('forever-monitor');
var child = new (forever.Monitor)('your-filename.js', {
max: 3,
silent: true,
options: []
});
child.on('exit', function () {
console.log('your-filename.js has exited after 3 restarts');
});
child.start();
You should take a minute and read over the options available in the excellent documentation for Forever in the README.md
You have a number of events that can be listened for in Forever as well:
error [err]: Raised when an error occurs
start [process, fvrFile, data]: Raise when the target script is first started.
stop [process]: Raised when the target script is stopped by the user
save [path, data]: Raised when the target Monitor saves the pid information to disk.
restart [forever]: Raised each time the target script is restarted
exit [forever]: Raised when the target script actually exits (permenantly).
stdout [data]: Raised when data is received from the child process' stdout
stderr [data]: Raised when data is received from the child process' stderr
It does this by attaching event listeners to the script you're trying to run and handling them in a graceful manner.
The code is pretty well documented if you want to take a look at exactly how it does it.
You should also read this excellent tutorial on how to keep a process running forever.
As for the second question: No, it does not add it to start at boot. For that, you'd need to add it as an upstart job or use something like Monit to monitor and start it. For that, you should take a look at Deploying Node.js with Upstart and Monit. It's a great tutorial.
This is an old post, but I stumbled across this on Google - its a little out of date, as forever branched the command line version from the programatic version. You need to use forever-monitor instead of forever. The example code should now be;
var forever = require('forever-monitor');
var child = new (forever.Monitor)('your-filename.js', {
max: 3,
silent: true,
options: []
});
child.on('exit', function () {
console.log('your-filename.js has exited after 3 restarts');
});
child.start();
I tried to suggest an edit to the original answer, but the powers that be rejected it. Figured I could spare some others the time it took me to figure out why the example code doesn't work :-)

Resources