Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Release v0.0.31

  • Loading branch information...
commit 18c027572e822539a7cbc6bccc49b2a9f4d8ea52 1 parent 6ea2c74
@pgte authored
View
6 ChangeLog
@@ -1,3 +1,9 @@
+2010.10.20 v0.0.31
+
+* Kill workers if they aren't dead after 30 seconds.
+* New option worker_kill_timeout - when master is stopping, time to let workers kill themselves before REALLY killing them (miliseconds). defaults to 30000 (30 seconds).
+* Throws Error instances instead of strings when something goes wrong.
+
2010.10.11 v0.0.30
* Protected worker killing from throwing an exception when the worker is no longer there, in order to not compromise the whole shutdown process.
View
1  README.markdown
@@ -56,6 +56,7 @@ For UNIX sockets:
* daemonize : to fork and detach
* master_pid_path : master PID file path. If not passed in, no pid file is written
* worker_to_master_ping_interval : the interval by which children ping master to know if it's alive. in milliseconds. defaults to 30000 (30 seconds)
+* worker_kill_timeout - when master is stopping, time to let workers kill themselves before REALLY killing them (miliseconds). defaults to 30000 (30 seconds)
### How to reload
View
2  TODO
@@ -10,5 +10,5 @@
10. (DONE) Tests for these features: set gid, uid; set working dir; Redirect stdout to log files; daemonize properly.
11. (DONE) On sudden master death, somehow the workers should eventually realize that their master has died and kill themselves.
12. (DONE) Worker should notify master that he is also listening, so master can more accurately count him in in order to invoke the options.started callback.
-13. Worker should have a timeout when shutting down to prevent a client from hanging the process forever. Should be an option. default = 1 min?
+13. (DONE) Worker should have a timeout when shutting down to prevent a client from hanging the process forever. Should be an option. default = 1 min?
14. Support a development mode, where any changes to the code trigger the master restart, much like nodemon - http://github.com/remy/nodemon
View
81 lib/fugue.js
@@ -6,6 +6,7 @@ var server_socket;
var master_socket_path;
var master_server;
var killer, respawner;
+var worker_kill_timeout;
var isMaster = exports.isMaster = function() {
return !process.env._FUGUE_WORKER;
@@ -26,33 +27,70 @@ exports.workerPids = function() {
var stop = exports.stop = function() {
if (isMaster()) {
+
+ var workers_are_all_dead = function() {
+ workers = [];
+ netBinding = process.binding('net');
+ if (server_socket) netBinding.close(server_socket);
+ if (the_server) {
+ the_server.watcher.stop();
+ the_server = null;
+ }
+ server_socket = null;
+ if (master_server) {
+ master_server.close();
+ }
+ if (master_socket_path) {
+ // try to remove the
+ try {
+ require('fs').unlinkSync(master_socket_path)
+ } catch(excp) {
+ // do nothing
+ }
+ master_socket_path = null;
+ }
+ master_server = null;
+ process.removeListener('SIGINT', killer);
+ process.removeListener('SIGHUP', killer);
+ process.removeListener('SIGTERM', killer);
+ process.removeListener('SIGUSR2', respawner);
+ }
+
+ var workers_died = 0;
+
+ // kill all the hard way if they do not die
+ var kill_all_anyway_timeout = setTimeout(function() {
+ workers.forEach(function(worker) {
+ try {
+ if (worker) {
+ worker.kill('SIGKILL'); // Kill it dead
+ }
+
+ } catch(exxcp) {
+ // do nothing
+ }
+ });
+ workers_are_all_dead();
+ }, worker_kill_timeout);
+
workers.forEach(function(worker) {
worker.listeners('exit').forEach(function(listener) {
worker.removeListener('exit', listener);
});
try {
+ worker.on('exit', function() {
+ workers_died ++;
+ if (workers_died == workers.length) {
+ clearTimeout(kill_all_anyway_timeout);
+ workers_are_all_dead();
+ }
+ });
worker.kill();
} catch(excep) {
// do nothing, just log
console.log('Error killing worker with pid ' + worker.pid + ': ' + excep.message)
}
});
- workers = [];
- netBinding = process.binding('net');
- if (server_socket) netBinding.close(server_socket);
- if (the_server) {
- the_server.watcher.stop();
- the_server = null;
- }
- server_socket = null;
- if (master_server) {
- master_server.close();
- }
- master_server = null;
- process.removeListener('SIGINT', killer);
- process.removeListener('SIGHUP', killer);
- process.removeListener('SIGTERM', killer);
- process.removeListener('SIGUSR2', respawner);
}
}
@@ -78,7 +116,8 @@ exports.start = function(server, port, host, worker_count, options) {
gid : process.getgid(),
daemonize: false,
verbose: false,
- worker_to_master_ping_interval: 30000
+ worker_to_master_ping_interval: 30000,
+ worker_kill_timeout: 30000
}
if (options) {
(function(obj1, obj2) {
@@ -86,14 +125,16 @@ exports.start = function(server, port, host, worker_count, options) {
})(default_options, options);
}
options = default_options;
+
+ worker_kill_timeout = options.worker_kill_timeout;
var path = require('path');
// check if paths exist
if (!path.existsSync(options.tmp_path)) {
- throw "Temp path " + options.tmp_path + " does not exist. Please create it";
+ throw new Error("Temp path " + options.tmp_path + " does not exist. Please create it");
}
if (!path.existsSync(options.working_path)) {
- throw "Working path " + options.working_path + " does not exist. Please create it";
+ throw new Error("Working path " + options.working_path + " does not exist. Please create it");
}
@@ -295,7 +336,7 @@ exports.start = function(server, port, host, worker_count, options) {
// Save master PID
if (options.master_pid_path) {
fs.writeFile(options.master_pid_path, process.pid.toString(), function(error) {
- if (error) throw "Error saving master PID file in " + options.master_pid_path + ': ' + error;
+ if (error) throw new Error("Error saving master PID file in " + options.master_pid_path + ': ' + error);
});
}
View
2  package.json
@@ -1,6 +1,6 @@
{ "name" : "fugue"
, "description" : "Unicorn for node for node"
-, "version" : "0.0.30"
+, "version" : "0.0.31"
, "homepage" : "http://www.metaduck.com/fugue"
, "author" : "Pedro Teixeira <pedro.teixeira@gmail.com> (http://www.metaduck.com)"
, "contributors" :
Please sign in to comment.
Something went wrong with that request. Please try again.