gimm / gulp-express

gulp plugin for express
56 stars 26 forks source link

server.stop seems to leave command line prompt hanging #24

Closed jdann closed 9 years ago

jdann commented 9 years ago

I have a set of 3 gulp tasks that starts the server, runs some automated tests and then closes the server. However, when I run them the command prompt hangs after the server has been stopped.

Not sure if I have configured something wrong in gulp or if this is an issue with server,stop

GULP TASKS gulp.task('integration-express', function () { // Start the server at the beginning of the task return server.run({ file: paths.config + 'server.js' }); });

gulp.task('integration-run', ['integration-express'], function(){ var protractor = 'protractor ./config/protractor.conf.js'; return gulp.src('') .pipe(plumber()) .pipe(plugins.shell([protractor])) .pipe(gulp.dest('./dist')); });

gulp.task('integration', ['integration-run'], function(){ server.stop(); });

COMMAND LINE [14:13:16] Finished 'integration-run' after 22 s [14:13:16] Starting 'integration'... [14:13:16] Finished 'integration' after 523 µs Service process exited with code null SIGKILL ^CTerminate batch job (Y/N)?

gimm commented 9 years ago

I've added:

process.on('SIGINT', function(){
  process.exit();
});

please let me know this works for you

jdann commented 9 years ago

It's still hanging. I am getting the following now:

[08:40:46] Finished 'integration-run' after 1.45 min [08:40:46] Starting 'integration'... [08:40:46] Finished 'integration' after 409 µs Service process exited with [code => null | sig => SIGKILL] Service process exited with [code => undefined | sig => undefined] Service process exited with [code => 0 | sig => undefined]

gimm commented 9 years ago

Thanks for your feedback, I will look into this later. The Chinese New Year is coming, so please be patient😉

jdann commented 9 years ago

That's fine. Just to confirm the commands are being run from a Windows 7 PC

punmechanic commented 9 years ago

This appears to be something to do with tiny-lr. Removing the livereload functionality causes the task to end as expected. Been having this problem for the longest time myself. I'm going to look into it and see if I can dig something up while @gimm is celebrating new year

punmechanic commented 9 years ago

After poking around tiny-lr, I found it was starting a listen on a node http server, but gulp-express was not capturing the server, so when the child process of express ended, livereload was not having it's http server closed, and so the livereload server was keeping the task alive.

I fixed this by causing Server.prototype.listen in tiny-lr/server.js to return this.server and then changing the returned run method from gulp-express/index.js to the below

        run: function (args, options) {
            args = (util.isArray(args) && args.length) ? args : defaults.args;
            options = merge(defaults.options, options || {});

            var livereloadServer;

            if (node) { // Stop
                node.kill('SIGKILL');
                node = undefined;
                process.removeListener('exit', processExitListener);
            } else {
                livereloadServer = livereload.start(options.port);
            }

            node = child_process.spawn('node', args, options);
            node.stdout.setEncoding('utf8');
            node.stderr.setEncoding('utf8');
            node.stdout.on('data', listener.logData);
            node.stderr.on('data', listener.logData);
            node.on('exit', listener.nodeExit);
            process.on('exit', listener.processExit);
            node.on('exit', function() {
                // kill the livereload server if our child process exits
                livereloadServer.close();
            });
            //process.on('SIGINT', mainDownListener);

            return node;
        },

I also changed the livereload object at line 24 in index.js to the following

    var livereload = {
        start: function (port) {
            return lr.listen(port);
        },
        reload: function (fileName) {
            lr.changed({
                body: {
                    files: [fileName]
                }
            });
        }
    };

Now you can return the result of gulp-express's run method and gulp will terminate the task correctly. Not pretty but it works. This should do while we wait for @gimm to come up with a more permanent fix as I feel this is quite a hacky fix and wouldn't be comfortable putting it as a pull request.

TLDR: tiny-lr is spawning a child process and the child process spawned by gulp-express isn't killing it when it dies

gimm commented 9 years ago

@DanPantry thanks man, I have update the plugin:

nodeExit: function (code, sig) {
            console.log('Node process exited with [code => %s | sig => %s]', code, sig);
            lr.close();//this will close tiny-lr server when node process exit
        }

this should stop the hanging.

punmechanic commented 9 years ago

Glad to be of service.

--- Original Message ---

From: "Gimm Yu" notifications@github.com Sent: 20 February 2015 00:54 To: "gimm/gulp-express" gulp-express@noreply.github.com Cc: "Dan" dan.pantry@hotmail.com Subject: Re: [gulp-express] server.stop seems to leave command line prompt hanging (#24)

@DanPantry thanks man, I have update the plugin:

nodeExit: function (code, sig) {
            console.log('Node process exited with [code => %s | sig => %s]', code, sig);
            lr.close();//this will close tiny-lr server when node process exit
        }

this should stop the hanging.


Reply to this email directly or view it on GitHub: https://github.com/gimm/gulp-express/issues/24#issuecomment-75171020

jdann commented 9 years ago

Thank you both - that's fixed the problem for me