From 27781a6c98812da906b68272b96f0aaa034111bd Mon Sep 17 00:00:00 2001
From: Lloyd Hilaiel <lloyd@hilaiel.com>
Date: Tue, 13 Dec 2011 23:51:25 -0700
Subject: [PATCH] implement graceful shutdown of bcrypt compute processes.  fix
 bcrypt.get_rounds (was throwing an exception)

---
 bin/browserid | 14 +++++++-------
 bin/dbwriter  | 14 +++++++-------
 lib/bcrypt.js | 12 +++++++++++-
 3 files changed, 25 insertions(+), 15 deletions(-)

diff --git a/bin/browserid b/bin/browserid
index cefd1df60..253f0a481 100755
--- a/bin/browserid
+++ b/bin/browserid
@@ -164,13 +164,15 @@ views.setup(app);
 // #10 - if nothing else has caught this request, serve static files
 app.use(express.static(path.join(__dirname, "..", "resources", "static")));
 
+function doShutdown(readyForShutdownCB) {
+  require('../lib/bcrypt.js').shutdown();
+  db.close(readyForShutdownCB)
+}
+
 // #11 - calls to /code_update from localhost will restart the daemon,
 // this feature is not externally accessible and is only used by
 // the update logic
-shutdown.installUpdateHandler(app, function(readyForShutdown) {
-  logger.debug("closing database connection");
-  db.close(readyForShutdown)
-});
+shutdown.installUpdateHandler(app, doShutdown);
 
 // #11.5 - custom 404
 app.use(function(req, res,next) {
@@ -195,9 +197,7 @@ db.open(config.get('database'), function (error) {
   }
 
   // shut down express gracefully on SIGINT
-  shutdown.handleTerminationSignals(app, function(readyForShutdown) {
-    db.close(readyForShutdown)
-  });
+  shutdown.handleTerminationSignals(app, doShutdown);
 
   var bindTo = config.get('bind_to');
   app.listen(bindTo.port, bindTo.host, function() {
diff --git a/bin/dbwriter b/bin/dbwriter
index 691ce3ac0..ed992197f 100755
--- a/bin/dbwriter
+++ b/bin/dbwriter
@@ -125,13 +125,15 @@ wsapi.setup({
   only_write_apis: true
 }, app);
 
+function doShutdown(readyForShutdownCB) {
+  require('../lib/bcrypt.js').shutdown();
+  db.close(readyForShutdownCB)
+}
+
 // calls to /code_update from localhost will restart the daemon,
 // this feature is not externally accessible and is only used by
 // the update logic
-shutdown.installUpdateHandler(app, function(readyForShutdown) {
-  logger.debug("closing database connection");
-  db.close(readyForShutdown)
-});
+shutdown.installUpdateHandler(app, doShutdown);
 
 // open the databse
 db.open(config.get('database'), function (error) {
@@ -142,9 +144,7 @@ db.open(config.get('database'), function (error) {
   }
 
   // shut down express gracefully on SIGINT
-  shutdown.handleTerminationSignals(app, function(readyForShutdown) {
-    db.close(readyForShutdown)
-  });
+  shutdown.handleTerminationSignals(app, doShutdown);
 
   var bindTo = config.get('bind_to');
   app.listen(bindTo.port, bindTo.host, function() {
diff --git a/lib/bcrypt.js b/lib/bcrypt.js
index ecbc52cb7..704aea87a 100644
--- a/lib/bcrypt.js
+++ b/lib/bcrypt.js
@@ -1,6 +1,7 @@
 const
 computecluster = require('compute-cluster'),
-logger = require('../lib/logging.js').logger;
+logger = require('../lib/logging.js').logger,
+bcrypt = require('bcrypt');
 
 var cc = new computecluster({
   module: path.join(__dirname, "bcrypt-compute.js"),
@@ -17,6 +18,7 @@ cc.on('error', function(e) {
 });
 
 exports.encrypt = function(workFactor, password, cb) {
+  if (!cc) throw "bcrypt cluster is shut down";
   cc.enqueue({
     op: 'encrypt',
     factor: workFactor,
@@ -27,6 +29,7 @@ exports.encrypt = function(workFactor, password, cb) {
 };
 
 exports.compare = function(pass, hash, cb) {
+  if (!cc) throw "bcrypt cluster is shut down";
   cc.enqueue({
     op: 'compare',
     pass: pass,
@@ -38,4 +41,11 @@ exports.compare = function(pass, hash, cb) {
 
 exports.get_rounds = function(hash) {
   return bcrypt.get_rounds(hash);
+};
+
+exports.shutdown = function() {
+  if (cc) {
+    cc.exit();
+    cc = undefined;
+  }
 };
\ No newline at end of file
-- 
GitLab