-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Karma doesn't exit properly when using public api with the finish callback #1035
Comments
For now it looks for me like it is https://github.com/LearnBoost/socket.io/blob/0.9/lib/stores/memory.js#L137 that blocks node.js from exiting, digging deeper. |
This issue stops Karma's public API from working with gulp and has resulted in workarounds where child processes are spawned to start Karma servers because there's simply no non-fatal way to get the Karma server to go away. Related to #734 |
|
I pushed a branch illustrating the gulp issue:
The issue is much better with v0.12.9 vs v0.10.9 -- it just takes two Control + C to get it to die, whereas in v0.10.9 it didn't matter how many times you hit Control + C, you had to |
@cironunes, as pointed out by @lazd I can confirm now that most of the delays on exit are coming from socket.io:
Other than this there are smaller "timeout leaks" in Karma that I'm going to address over the weekend, but yes, socket.io is the main culprit here. We either need to configure it or shutdown properly. |
OK, so finally I've found 4 different I've opened PRs (linked from here) that "fix" most of the issues, the only remaining timeout is here: |
@pkozlowski-opensource great work! Thanks for fixing this. I merged your first PR. The timeouts you mentioned (launchers/process.js#25), that's a bug, see #946 If you can fix it, that would be great. It has to be cleared in processExit. Let me know if you need any info. |
@vojtajina thnx for merging the things. I didn't see #946 before but yes, it describes the only remaining timeout issue. I played a bit with the code and I'm pretty positive about a fix but would like to add a test for it as well. Anyway, will take care of #946. |
@pkozlowski-opensource This happens for me once per 20-30 builds - the test suite finishes successfully, but hangs at gulp's For reference, this is our gulp code: const gulp = require('gulp')
const {Server} = require('karma')
gulp.task('unit', function (done) {
new Server({
configFile: './karma.conf.coffee'
}, exitCode => {
if (exitCode == 0) {
done()
} else {
process.exit(exitCode)
}
}).start()
}) |
@bcherny Were you able to find the solution to your issue? I'm seeing the same thing happen (20-30 builds) and I'd really like to solve it. |
As a workaround, I am forcing the karma server to be executed in a separate process via 'gulp-multi-process' gulp.task('test', () => {
const config = parseConfig(path.resolve('test/karma.conf.js'));
const server = new karma.Server(config);
server.start();
});
gulp.task('multi', (cb) => {
return multiProcess(['test'], cb);
});
gulp.task('watch', () => {
gulp.watch(files, ['multi']);
}); In addition my karma config has autoWatch off, and singleRun on. Hence, I am using gulp to watch my files and delegating all the test tasks (including report generation) to karma. |
@Fernker Missed your comment - we still see this issue every 20-30 builds. When it happens, we restart the build, and it usually passes. I've noticed that it tends to happen more often when we are running multiple builds in parallel on a single environment. |
The problem remains for Karma 1.4.0 on Windows. Is there workaround for that? |
I've been experiencing the same issues and have noticed the following:
I have a couple work arounds, granted niether is perfect: // gulpfile.js
const path = require('path');
const gulp = require('gulp');
const karma = require('karma');
const minimist = require('minimist');
const ARGV = minimist(process.argv.slice(2));
/**
* Option 1
* Use a stopper in the `run_complete` event listener.
* Must have access to the port the server is running on.
*/
gulp.task('karma_1', function taskKarma_1(taskDone){
/**
* if `--single` was a command line option, for example:
* `gulp karma_1 --single`
*/
var someConditionIsTrue = (ARGV.single === true);
var karmaConfig = {
autoWatch: true,
configFile: path.resolve('./karma.conf.js'),
port:9876, // Stopper will need to know the port.
singleRun: false
};
if(someConditionIsTrue){
karmaConfig.singleRun = true;
karmaConfig.autoWatch = false;
}
var karmaServer = new karma.Server(
karmaConfig,
function handleKarmaServerExit(processExitCode){
if(processExitCode === 0 || processExitCode === null || typeof processExitCode === 'undefined'){
taskDone();
} else {
var err = new Error('ERROR: Karma Server exited with code "' + processExitCode + '"');
taskDone(err);
}
}
);
if(karmaConfig.singleRun){
//Stop the server after the first run.
karmaServer.on('run_complete', function(){
karma.stopper.stop({
port: karmaConfig.port
});
});
}
karmaServer.start();
});
/**
* Option 2
* Use `process.exit` in the Karma onExit handler.
*/
gulp.task('karma_2', function taskKarma_2(taskDone){
/**
* if `--single` was a command line option, for example:
* `gulp karma_2 --single`
*/
var someConditionIsTrue = (ARGV.single === true);
var karmaConfig = {
autoWatch: true,
configFile: path.resolve('./karma.conf.js'),
singleRun: false
};
if(someConditionIsTrue){
karmaConfig.singleRun = true;
karmaConfig.autoWatch = false;
}
var karmaServer = new karma.Server(
karmaConfig,
function handleKarmaServerExit(processExitCode){
if(processExitCode === 0 || processExitCode === null || typeof processExitCode === 'undefined'){
taskDone();
} else {
var err = new Error('ERROR: Karma Server exited with code "' + processExitCode + '"');
taskDone(err);
}
process.exit(processExitCode); //Exit the node process
}
);
karmaServer.start();
}); I hope this helps! |
I should add clarification. The server exit handler is being called for me, but the process never exits if the affected browsers are launched. In hindsight, this may be different from the issue described above. My "option 2" is similar to @bcherny 's code. |
Windows 7 I've run into the same issue, tested on [email protected] and karma@latest in my project's gulp chain. Seems there are socket.io handlers (detected using why-is-node-running) that aren't resolved for a good 30-40 seconds after karma has finished executing the tests. The above solutions provided by @npetruzzelli are of no help as they terminate the node process and the following tasks are not executed. I was hoping #3149 would help but it seems that despite Karma exiting gracefully after the test run it seems socket.io is still holding the process hostage. I'm going to try what was suggested by @jnwu but I'm not sure this is the best solution to the problem. |
Using Karma's server public API with a done callback makes the whole node process "stuck" - there are probably some event listeners that prevent node process from exiting properly. A simple reproduce scenario:
Interestingly, removing the flash from the list of transports make the Karma exit after a while (~20s after test are finished on my machine).
There is a small repo with the reproduce scenario here:
https://github.com/karma-runner/gulp-karma/blob/exit_pb/exitTest.js
I will be digging into the topic but any help from someone more knowledgeable about Karma internals would be highly appreciated.
The text was updated successfully, but these errors were encountered: