Killing a Node.js program from a shell script - javascript

I'm running a node.js application which is acting as a man-in-the-middle proxy to proxy all of the requests I'm making through a PhantomJS headless testing environment. I want to spin up this proxy from either my PhantomJS test script (though I've looked into it and it seems that phantom does not have an exec() command for executing shell commands) or a small shell script which manages both processes. Ideally, it would do something like
#!/bin/bash
node proxy.js
phantomjs runTests.js
kill node process here
Is there any way that I can do this?

Moments after asking this question, I found a much better way to execute the phantom program from within my node app by using a child process. I placed my phantom script within the folder which contained my node app, and then used exec like this:
var exec = require('child_process').exec;
var _phantom = exec('phantomjs runTests.js',function(error,stdout,stderr){
console.log(stdout);
};
_phantom.on('exit',function(code,sig){
process.exit(code);
});
This means I could spin up my proxy server, then execute the child process. The _phantom.on('exit') block allows me to detect when the process exits on a code. Then, it's very simple to signal the node app to quit, using process.exit.

Related

What is best practice for executing Node.js app in production on a WINDOWS machine?

I have a Node.js application that I require to run on Windows Server. For the development process, we execute the app simply through command-line or PowerShell using the standard command:
node index.js
What is the best practice and most performant way of running this application on Windows permanently? Or is running it through CMD or PowerShell as we already doing the best way? If so, is either PS or CMD better?
Running as a service is a no-brainer, but the question still remains even if the application is 'servicified', as launching a Node app as a service still requires the specification of a shell through which to execute, such as PowerShell or CMD. Is there another shell we should use? Or is there a way to not use a shell at all?
Please advise as it surprisingly doesn't seem like there's any standardized advice anywhere on the internet; which begs the question also: is simply no one out there running production Node.js apps on Windows perhaps..?
I suggest using a package such as pm2.
PM2 runs your process in the background. Meaning that you can exit your terminal, and your app will continue to run. Only way to turn it off is:
1: Shutting down your server
2: pm2 stop ProcessName

Node spawn child process doesn't execute the command after exec child process in aws node 10 lambda

I am attempting to run 2 child processes, but one seems to be blocked and eventually times out the node lambda.
Environment:
AWS node 10 lambda running in a docker container.
Accesses ffmpeg and ffprobe via a lambda layer in the /opt/bin directory.
child_process.exec
I am running ffprobe in a child_process.exec to get the file format of an audio file. I am using exec because the output is a small json response (which shouldn't consume much memory).
child_process.spawn
Shortly after I run ffmpeg to convert the audio file to mp3 using child_process.spawn.
The problem is the FFMPEG child_process.spawn command doesn't run after ffprobe (even though ffprobe successfully completes). If I don't run the ffprobe command the FFMPEG command runs perfectly.
Which leads me to believing this is an issue with how I am dealing with child processes in node.
Is it possible the child_process.exec ffprobe command is somehow still running/ blocking the new ffmpeg (child_process.spawn) command from running - if so how do I check this?
When I access the running processes in the docker container only the new ffmpeg command seems to be running, although it consumes no memory and just hangs - seemingly doing nothing. I even tried launching the ffmpeg command from the docker cli (avoiding using the node env) and this works fine and runs as expected.
So it seems my issue wasn't really between exec and spawn, I am not 100% sure but I think it could be that the child process was preserved in the container and resumed in the next invocation of the lambda.
Changing to child_process.spawnSync waits until the child process exits and keeps things cleaner and I haven't encountered this problem since using this.
A more thorough explanation from someone else would be really appreciated.

How to fork a child process with electron

I have a simple nodeJS app that has a function to scrape file metadata. Since scraping metadata can be intensive I made the app run this as a child process using fork.
const metaParser = child.fork( fe.join(__dirname, 'parse-metadata.js'), [jsonLoad]);
Everything worked great until I ported this to electron. When run in main.js the process is successfully created, but immediately exits. I added some logging to parse-metadata.js and found out that parse-metadata.js executed successfully and ran long enough to run the first few lines of code and then exited.
How do I get electron to fork parse-metadata.js and keep it alive until the end?
I'm using electron v1.4.15 and Node v6
When using the detached option to start a long-running process, the process will not stay running in the background unless it is provided with a stdio configuration that is not connected to the parent.
Also it seems related to the env.
Look at this: https://github.com/electron/electron/issues/6868

Automate UI testing with Javascript, node - starting & stopping a web server

I'm currently investiagating automated UI testing using JavaScript on windows with node.js and phantom.js and unsurprisingly I've found many frameworks that can help in this regard (casper.js, Buster.js, etc).
The one thing that seems to be missing from the frameworks I have looked at so far is stopping and starting a web server to server the web pages so that testing framework can perform its testing. One exception is WebDriver.js which uses the Selenium standalone server but this relies on a server written Java and at the moment I'd prefer to find a node based solution if at all possible.
From the node perscpective I've looked at Connect.js and also Http-Server (which I particularly like) but the issue is starting and stopping these from a JavaScript test.
I've attempted to create a casper.js test that would interact with a server, run the test and then stop the server but I can't get it to work, here's an example script
var childProcess = require('child_process').spawn('http-server', '/TestSite');
casper.test.begin("Load-page", 1, function suite(test){
casper.start('http://localhost:8080/',function(){
test.assertTitle("test page");
});
casper.run(function(){
test.done();
childProcess.kill();
});
});
I call this from the command line using the following command (casper is in my Path variable):
casperjs Load-page testFile.js
What I was hoping would happen is the http-server would start, casper would start the test and then after the test was run the http-server would be killed.
I've also tried similar with Connect:
var server= connect.createServer(connect.static('/TestSite')).listen(8080)
casper.test.begin("Load-page", 1, function suite(test){
casper.start('http://localhost:8080/',function(){
test.assertTitle("test page");
});
casper.run(function(){
test.done();
server.stop();
});
});
But again with no luck.
I can run the Casper sample tests which work and I've also got Node in my Path as well and can call the REPL from the command prompt.
The directory structure is:
Code
/TestSite
/node_modules
and I run the tests from the Code folder.
Am I simply unable to do this or am I just not getting how it should work?
When you say "no luck" what do you mean?
The connect example looks mostly OK, and I'd prefer it over spawning a subprocess. Bear in mind that listen is potentially async so the server might not be available immediately though. The second param to listen is a callback that will be run once the server is listening - maybe try running the tests in that callback instead?
Pro Tip: Don't rely on port 8080 always being free on whatever machine you're running on - passing in 0 for the port will cause the server to start on a random port, you can then do server.address().port in the listen callback to get the port that was chosen
I managed to get it working using a combination of differebt scripts and using child_process spawn.
I created a script called startServer.js that would start the server using Connect:
var connect = require('connect');
var server= connect.createServer(connect.static('TestSite'));
server.listen(8081);
I created another script runTests.js that would call the server script via spawn and then call Casper, again via spawn, and run all the capser tests that are in a folder called tests relative to where the script is run from.
var child_process = require('child_process');
var stillRunning = true;
var server = child_process.spawn('node', ['createServer.js']);
var casper = child_process.spawn('casperjs', ['test tests']);
casper.stdout.on('data', function(data){
console.log(data.toString());
});
casper.stderr.on('data', function(data){
console.log('Error: ' + data);
});
casper.on('exit', function(code){
server.kill();
process.exit(0);
});
To use this at the command prompt navigate to the folder where the script is and then run node runTests.js and the server will be started and the tests run against the site

Can programs be written with JavaScript that run Windows 8 terminal commands when a gui button is clicked?

I know Windows 8 'apps' can be developed using web technologies but I haven't been able to find out if terminal commands can be run in the background using web technologies as an interface. I basically have mongoDB on my computer and it takes two terminal windows open to run it. I thought it might be a neat project to see if I could write a little app that is nothing more than a button that launches both commands behind the scenes saving me the hassle of going to the directories and running the commands manually for both terminal windows.
If you plan to launch apps via server-side JavaScript (e.g. node.js), use the child_process module..
The workflow would be that in the windows 8 gui side, it will just issue a request to your own local server in node.js, then it would execute those commands.
Example:
var exec = require('child_process').exec;
var child = exec("insert command here", function(err, stdout, stderr) { });
See examples exec and spawn for more examples.
======
Another thing you can do is create a batch (.bat) file that contains those two commands needed for your mongodb instance and put that as a shortcut in the Windows 8 Start Screen.
It depends on what kinds of commands you need to execute, and when and where. If you plan to execute commands remotely, I'd assume server-side JS would be appropriate, but if you plan to execute commands locally, I think all you need is just batch scripting.

Categories