Make halting on SIGINT async

This change gives adaptors/drivers more flexibility in halting. Additionally,
now, by default, all Adaptors/Drivers will remove all their event listeners
before halting, which should prevent some additional commands from being sent to
the adaptor during shutdown.
This commit is contained in:
Andrew Stewart 2014-06-12 15:31:49 -07:00
parent a44154b1f4
commit 6de922f2fc
6 changed files with 50 additions and 15 deletions

View File

@ -52,7 +52,11 @@ Adaptor.prototype.connect = function(callback) {
// Public: Disconnects from the adaptor // Public: Disconnects from the adaptor
// //
// callback - function to run when the adaptor is disconnected
//
// Returns nothing // Returns nothing
Adaptor.prototype.disconnect = function() { Adaptor.prototype.disconnect = function(callback) {
Logger.info("Disconnecting from adaptor '" + this.name + "'."); Logger.info("Disconnecting from adaptor '" + this.name + "'.");
this.removeAllListeners();
callback();
}; };

View File

@ -84,8 +84,10 @@ Connection.prototype.connect = function(callback) {
// Public: Disconnect the adaptor's connection // Public: Disconnect the adaptor's connection
// //
// callback - function to be triggered then the adaptor has disconnected
//
// Returns nothing // Returns nothing
Connection.prototype.disconnect = function() { Connection.prototype.disconnect = function(callback) {
var msg = "Disconnecting from '" + this.name + "'"; var msg = "Disconnecting from '" + this.name + "'";
if (this.port != null) { if (this.port != null) {
@ -95,7 +97,7 @@ Connection.prototype.disconnect = function() {
msg += "."; msg += ".";
Logger.info(msg); Logger.info(msg);
return this.adaptor.disconnect(); return this.adaptor.disconnect(callback);
}; };
// Public: sets up adaptor with @robot // Public: sets up adaptor with @robot
@ -111,8 +113,10 @@ Connection.prototype.initAdaptor = function(opts) {
// Public: Halt the adaptor's connection // Public: Halt the adaptor's connection
// //
// callback - function to be triggered when the connection has halted
//
// Returns nothing // Returns nothing
Connection.prototype.halt = function() { Connection.prototype.halt = function(callback) {
var msg = "Halting adaptor " + this.name; var msg = "Halting adaptor " + this.name;
if (this.port != null) { if (this.port != null) {
@ -120,5 +124,5 @@ Connection.prototype.halt = function() {
} }
Logger.info(msg); Logger.info(msg);
return this.disconnect(); return this.disconnect(callback);
}; };

View File

@ -8,6 +8,8 @@
"use strict"; "use strict";
var Async = require('async');
var API = require('./api'), var API = require('./api'),
Logger = require('./logger'), Logger = require('./logger'),
Robot = require('./robot'), Robot = require('./robot'),
@ -73,11 +75,21 @@ Cylon.start = function start() {
// Public: Halts the API and the robots // Public: Halts the API and the robots
// //
// callback - callback to be triggered when Cylon is ready to shutdown
//
// Returns nothing // Returns nothing
Cylon.halt = function halt() { Cylon.halt = function halt(callback) {
// set a timeout, in case trying to shut everything down nicely doesn't work
Utils.after((1.5).seconds(), callback);
var fns = [];
for (var bot in this.robots) { for (var bot in this.robots) {
this.robots[bot].halt(); var robot = this.robots[bot];
fns.push(robot.halt.bind(robot));
} }
Async.parallel(fns, callback);
}; };
if (process.platform === "win32") { if (process.platform === "win32") {
@ -90,6 +102,7 @@ if (process.platform === "win32") {
}; };
process.on("SIGINT", function() { process.on("SIGINT", function() {
Cylon.halt(); Cylon.halt(function() {
process.kill(process.pid); process.kill(process.pid);
});
}); });

View File

@ -62,10 +62,12 @@ Device.prototype.start = function(callback) {
// Public: Halt the device driver // Public: Halt the device driver
// //
// callback - function to trigger when the device has been halted
//
// Returns result of supplied callback // Returns result of supplied callback
Device.prototype.halt = function() { Device.prototype.halt = function(callback) {
Logger.info("Halting device '" + this.name + "'."); Logger.info("Halting device '" + this.name + "'.");
return this.driver.halt(); this.driver.halt(callback);
}; };
// Public: Expresses the Device in JSON format // Public: Expresses the Device in JSON format

View File

@ -52,7 +52,11 @@ Driver.prototype.start = function(callback) {
// Public: Halts the driver // Public: Halts the driver
// //
// callback - function to be triggered when the driver is halted
//
// Returns nothing // Returns nothing
Driver.prototype.halt = function() { Driver.prototype.halt = function(callback) {
Logger.info("Driver " + this.name + " halted."); Logger.info("Driver " + this.name + " halted.");
this.removeAllListeners();
callback();
}; };

View File

@ -275,15 +275,23 @@ Robot.prototype.startDevices = function(callback) {
// //
// Halts the devices, disconnects the connections. // Halts the devices, disconnects the connections.
// //
// callback - callback to be triggered when the Robot is stopped
//
// Returns nothing // Returns nothing
Robot.prototype.halt = function() { Robot.prototype.halt = function(callback) {
var fns = [];
for (var d in this.devices) { for (var d in this.devices) {
this.devices[d].halt(); var device = this.devices[d];
fns.push(device.halt.bind(device));
} }
for (var c in this.connections) { for (var c in this.connections) {
this.connections[c].halt(); var connection = this.connections[c];
fns.push(connection.halt.bind(connection));
} }
Async.parallel(fns, callback);
}; };
// Public: Initialize an adaptor and adds it to @robot.adaptors // Public: Initialize an adaptor and adds it to @robot.adaptors