Fix race condition in 'meteor mongo'.

The 'exit' event on a ChildProcess doesn't necessarily occur before all the
'data' events on its stdio, so sometimes 'meteor mongo' didn't find the
process. We should have been using the 'close' event. Switch from
child_process.spawn to child_process.exec, which simplifies the code and uses
the right event.
This commit is contained in:
David Glasser
2013-01-03 09:29:52 -08:00
parent fb24d39cba
commit 203a82d9b9

View File

@@ -1,6 +1,6 @@
var fs = require("fs"); var fs = require("fs");
var path = require("path"); var path = require("path");
var spawn = require('child_process').spawn; var child_process = require('child_process');
var files = require(path.join(__dirname, '..', 'lib', 'files.js')); var files = require(path.join(__dirname, '..', 'lib', 'files.js'));
@@ -15,37 +15,34 @@ var _ = require('underscore');
*/ */
var find_mongo_pids = function (app_dir, port, callback) { var find_mongo_pids = function (app_dir, port, callback) {
// 'ps ax' should be standard across all MacOS and Linux. // 'ps ax' should be standard across all MacOS and Linux.
var proc = spawn('ps', ['ax']); child_process.exec('ps ax',
var data = ''; function (error, stdout, stderr) {
proc.stdout.on('data', function (d) { if (error) {
data += d; callback({reason: error});
}); } else if (stderr) {
callback({reason: 'ps produced stderr ' + stderr});
} else {
var pids = [];
proc.on('exit', function (code, signal) { _.each(stdout.split('\n'), function (ps_line) {
if (code === 0) { // matches mongos we start.
var pids = []; var m = ps_line.match(/^\s*(\d+).+mongod .+--port (\d+) --dbpath (.+)(?:\/|\\)\.meteor(?:\/|\\)local(?:\/|\\)db\s*$/);
if (m && m.length === 4) {
var found_pid = parseInt(m[1]);
var found_port = parseInt(m[2]);
var found_path = m[3];
_.each(data.split('\n'), function (ps_line) { if ( (!port || port === found_port) &&
// matches mongos we start. (!app_dir || app_dir === found_path)) {
var m = ps_line.match(/^\s*(\d+).+mongod .+--port (\d+) --dbpath (.+)(?:\/|\\)\.meteor(?:\/|\\)local(?:\/|\\)db\s*$/); pids.push({
if (m && m.length === 4) { pid: found_pid, port: found_port, app_dir: found_path});
var found_pid = parseInt(m[1]); }
var found_port = parseInt(m[2]);
var found_path = m[3];
if ( (!port || port === found_port) &&
(!app_dir || app_dir === found_path)) {
pids.push({
pid: found_pid, port: found_port, app_dir: found_path});
} }
} });
});
callback(null, pids); callback(null, pids);
} else { }
callback({reason: 'ps exit code ' + code}); });
}
});
}; };
@@ -162,7 +159,7 @@ exports.launch_mongo = function (app_dir, port, launch_callback, on_exit_callbac
return; return;
} }
var proc = spawn(mongod_path, [ var proc = child_process.spawn(mongod_path, [
'--bind_ip', '127.0.0.1', '--bind_ip', '127.0.0.1',
'--smallfiles', '--smallfiles',
'--port', port, '--port', port,