I want to wait for a server to be ready, then run a task on top of it
EDIT:
I've got some of this figured out. I am properly filtering for my string. However, how can I keep this running in the background, and have it terminate when a grunt sequence is complete?
Consider
grunt common server spec-e2e
This will run the common tasks, run the grunt server, then (without stopping the server) runs the next task on top. After all of this is complete, it turns off the server automatically.
That's the kind of functionality that I'm trying to create.
A couple important points that I learned:
Processes started from node - e.g. require('child_process').spawn(...) - will continue to run for all subsequent grunt tasks (they won't be closed once the single task completes).
Once grunt is finished running the sequence of tasks, it will terminate all spawned processes.
Therefore, the command grunt selendroid:selendroid.jar spec-e2e - where the selendroid task starts a server - will keep the server running until after the spec-e2e task completes.
The code for my selendroid task is:
grunt.registerTask('selendroid', 'Start selendroid server', function (appLocation) {
var done = this.async();
var timeout = setTimeout(function() {
console.log('Selendroid took too long to start');
done(false);
}, 30000);
function checkLoaded(data) {
data = data.toString();
if (data.indexOf('Selendroid standalone server has been started on port') > -1) {
clearTimeout(timeout);
done();
}
}
if (typeof appLocation === 'undefined') {
console.log('App to test not set, aborting...'.red);
done(false);
}
var cmd = require('child_process').spawn('java', ['-jar', 'selendroid.jar', '-app', appLocation]);
cmd.stdout.on('data', function(data) {
checkLoaded(data);
});
cmd.stderr.on('data', function(data) {
checkLoaded(data);
});
});
Related
I'm using this code in my own app:
pm2.restart('myapp', function() {});
Works fine, but how can I include delayed restart to that?
--restart-delay=3000
As mentioned in the API docs you should define this configuration "restartDelay" in your Start function, the restart only stop and start it again:
pm2.start({
name : 'myapp', // Script name
script : 'app.js', // Script to be run
exec_mode : 'cluster', // Allows your app to be clustered
restartDelay : 3000, // Number of ms to wait before restarting the script
}, function(err, apps) {
pm2.disconnect(); // Disconnects from PM2
if (err) throw err
});
I have a bash script that I am running server side from meteor. I have tested that I am successfully able to run shell commands by running 'ls' and getting the expected response back. However, when I run my shell script no output is ever logged to the server console and none of the intended effects of the script are successful. I am printing stderr,stdout, and error yet they print nothing when I run my script.
Meteor.methods({
grade: function(unittest, code) {
this.unblock();
var sys = Npm.require('sys');
var exec = Npm.require('child_process').exec;
// exec('/bin/ls /srv/srcalyzer/scripts', function(error,stdout,stderr){
// console.log('error: ',error);
// console.log('stdout: ',stdout);
// console.log('stderr: ',stderr);
// });
console.log('running grade')
exec('/bin/bash /srv/srcalyzer/scripts/grade.sh', function(error,stdout,stderr){
console.log('error: ',error);
console.log('stdout: ',stdout);
console.log('stderr: ',stderr);
});
console.log('just finished.');
},
Although it is currently commented out the /bin/ls /some/path logs the expected output to console. However when I run the /bin/bash /path/to/.sh that I know is in place. The console output looks like
I20161207-15:22:07.031(-5)? running grade
I20161207-15:22:07.045(-5)? just finished.
The script does take a short time to run (~15-20 seconds). I am uncertain if this is relevant or not.
Can someone please help me understand what is happening?
there's a hint here:
I20161207-15:22:07.031(-5)? running grade
I20161207-15:22:07.045(-5)? just finished.
that's only taking a few ms to run. meaning, your Meteor method is likely exiting before the exec() finishes. i've never run an exec() in Meteor, so i'm unsure if that shell script keeps running after your method exits.
what you need is to run a future in your Meteor method, so it doesn't exit until your shell script comes back.
something like:
let future = new Future();
exec('/bin/bash /srv/srcalyzer/scripts/grade.sh', function(error,stdout,stderr){
console.log('error: ',error);
console.log('stdout: ',stdout);
console.log('stderr: ',stderr);
future.return(stdout.toString());
});
return future.wait();
now your Meteor method will wait until your script finishes.
(caveat: i didn't try this, just typing this solution from memory on my non-work machine)
Here is my setup.
I have a grunt task that does 2 things: 1) start a http server listening on some port 2) triggers another grunt task
The grunt task triggered above is a testem task that runs tests on test-index.html page in PhantomJS.
The test-index.html page sends a POST call on the port on which I start a server in the first grunt task.
Issue: The POST call doesn't hit my server.
Note: If I run the same server manually (not from grunt) and then run the test grunt task, the POST call hits the server.
Heres the code:
Grunt task
grunt.registerMultiTask('coverage', 'Generates coverage reports for JS using Istanbul', function () {
var server = http.createServer(function(req, resp) {
resp.setHeader("Access-Control-Allow-Origin", "*");
console.log('Got something');
req.pipe(fs.createWriteStream('coverage.json'))
resp.end();
});
var port = 7358;
server.listen(port);
// This task simply executes a command: `testem.js ci`
grunt.task.run('testem').then(function() {
server.close();
});
});
test-index.html (somewhere in the )
function onTestemLoad() {
Testem.on('all-test-results', function(results){
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:7358/');
xhr.send(JSON.stringify(window.__coverage__))
});
}
Can anyone point what might be going wrong here?
you've been misled by grunt.task.run!
This line does NOT run the task, it just puts it on the top of the list of tasks to run once the current task is done (http://gruntjs.com/api/grunt.task#grunt.task.run).
A second issue is that when a task completes, it takes down all its running processes with it.
So what happens is:
coverage starts, spins on your server, then register testem as next task
coverage ends, taking down your server
next task (= testem) runs, but no server is here to answer...
You can fix it by doing the following 2 things:
inline your test: replace grunt.task.run('testem') with a direct call to testem
ensure your tests run synchronously - or keep your task alive until your tests are done (using this.async - see http://gruntjs.com/api/inside-tasks#this.async).
I have grunt task that starts the server:
module.exports = function(grunt){
grunt.registerMultiTask('connect', 'Run a simple Node Server', function(){
var options = this.options();
// Tell Grunt this task is asynchronous.
var done = this.async();
var server = connect();
server.use(function(request, response, nxt){
...
});
server.listen(port);
});
};
Now I want to use grunt to start this node server first and then open the browser using grunt-open plugin.
grunt.task.run(['startServer', 'open']);
But startServer task in blocking the open task as the server keeps on listening. What should I do to keep this node server running and open the browser once the server starts?
I had the same problem as yours and I worked in Windows environment. My solution was to put the web server codes in a file for example myServer.js, and use cmd: "start node \"path\to\myServer.js" within the grunt-exec settings.
Example:
Let's assume my server file is located on the following path: D:\SourceCodes\WebServer\myServer.js
ip address and port of my server is 192.168.1.1:8080,
and my webpage is index.html
Then the Gruntfile.js would be:
module.exports = function (grunt) {
grunt.initConfig({
exec: {
run_server:{
cwd: "D:/SourceCodes/WebServer/",
cmd: "start node \"D:/SourceCodes/WebServer/myServer.js\""
},
open_web:{
cmd: "start chrome http://192.168.1.1:8080/index.html"
}
});
grunt.loadNpmTasks('grunt-exec');
grunt.registerTask('default', ['exec']);
}
Two things:
your 'connect' task currently blocks while waiting, you have to tell it to let the grunt process run asynchronously: call done() at the end
...
server.listen(port);
done();
});
now your build will end at the end of your task list, and take down your server with it. So you have to add a task to keep it alive. I suggest using grunt-contrib-watch, but you may choose any one you like, as long as it's a blocking task:
grunt.task.run(['startServer', 'open', 'watch]);
By the way, why are you calling grunt.task.run instead of defining your own task sequence grunt.registerTask('default', ['startServer', 'open', 'watch]); ?
I've an app which initially creates static config files (once) and after files were written I need to reinitialize/restart the application.
Is there something to restart a node.js app from itself?
This is required cause I've an application running in two runlevels in node.js.
The initial one starts completly synchronus and after this level has been completed app is in async runlevel in a previously started environment.
I know there are tools like nodemon but that's not what I need in my case.
I tried to kill the app via process.kill() which is working but I can't listen to the kill event:
// Add the listener
process.on('exit', function(code) {
console.log('About to exit with code:', code);
// Start app again but how?
});
// Kill application
process.kill();
Or is there a better, cleaner way to handle this?
Found a working case to get node.js restarted from app itself:
Example:
// Optional part (if there's an running webserver which blocks a port required for next startup
try {
APP.webserver.close(); // Express.js instance
APP.logger("Webserver was halted", 'success');
} catch (e) {
APP.logger("Cant't stop webserver:", 'error'); // No server started
APP.logger(e, 'error');
}
// First I create an exec command which is executed before current process is killed
var cmd = "node " + APP.config.settings.ROOT_DIR + 'app.js';
// Then I look if there's already something ele killing the process
if (APP.killed === undefined) {
APP.killed = true;
// Then I excute the command and kill the app if starting was successful
var exec = require('child_process').exec;
exec(cmd, function () {
APP.logger('APPLICATION RESTARTED', 'success');
process.kill();
});
}
The only con I can see here is to loose outputs on console but if anything is logged into logfiles it's not a problem.