From 1971ecc8175c4305469c4b82d08c697b1af70a4a Mon Sep 17 00:00:00 2001
From: Lloyd Hilaiel <lloyd@hilaiel.com>
Date: Fri, 23 Mar 2012 13:05:07 -0600
Subject: [PATCH] add a ping wsapi that's registered on all daemons and does a
 light weight test of database health - closes #1324

---
 lib/db/mysql_wrapper.js     |  8 +++++++-
 lib/wsapi.js                |  6 ++++--
 lib/wsapi/ping.js           | 16 ++++++++++++++++
 tests/stalled-mysql-test.js | 24 ++++++++++++++++++++++++
 4 files changed, 51 insertions(+), 3 deletions(-)
 create mode 100644 lib/wsapi/ping.js

diff --git a/lib/db/mysql_wrapper.js b/lib/db/mysql_wrapper.js
index 91c463482..45edfd7de 100644
--- a/lib/db/mysql_wrapper.js
+++ b/lib/db/mysql_wrapper.js
@@ -40,7 +40,13 @@ exports.createClient = function(options) {
       });
     },
     ping: function(cb) {
-      this.realClient.ping(cb);
+      if (stalled) {
+        process.nextTick(function() {
+          cb("database is intentionally stalled");
+        });
+      } else {
+        this.realClient.ping(cb);
+      }
     },
     _runNextQuery: function() {
       var self = this;
diff --git a/lib/wsapi.js b/lib/wsapi.js
index e23a50ce9..7ee1f4a8d 100644
--- a/lib/wsapi.js
+++ b/lib/wsapi.js
@@ -251,8 +251,10 @@ exports.setup = function(options, app) {
     try {
       var api = require(path.join(__dirname, 'wsapi', f));
 
-      // don't register read apis if we are configured as a writer
-      if (options.only_write_apis && !api.writes_db) return;
+      // don't register read apis if we are configured as a writer,
+      // with the exception of ping which tests database connection health.
+      if (options.only_write_apis && !api.writes_db &&
+          operation != 'ping') return;
 
       wsapis[operation] = api;
 
diff --git a/lib/wsapi/ping.js b/lib/wsapi/ping.js
new file mode 100644
index 000000000..e1847ef09
--- /dev/null
+++ b/lib/wsapi/ping.js
@@ -0,0 +1,16 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const db = require('../db.js');
+
+exports.method = 'get';
+exports.writes_db = false;
+exports.i18n = false;
+
+exports.process = function(req, res) {
+  db.ping(function(err) {
+    if (err) res.send("fail", 500);
+    else res.send("ok",200);
+  });
+};
diff --git a/tests/stalled-mysql-test.js b/tests/stalled-mysql-test.js
index a07535527..cd40adba4 100755
--- a/tests/stalled-mysql-test.js
+++ b/tests/stalled-mysql-test.js
@@ -77,6 +77,13 @@ suite.addBatch({
 
 // now try all apis that can be excercised without further setup
 suite.addBatch({
+  "ping": {
+    topic: wsapi.get('/wsapi/ping', {}),
+    "fails with 500 when db is stalled": function(err, r) {
+      // address info with a primary address doesn't need db access.
+      assert.strictEqual(r.code, 500);
+    }
+  },
   "address_info": {
     topic: wsapi.get('/wsapi/address_info', {
       email: 'test@example.domain'
@@ -154,6 +161,16 @@ addStallDriverBatch(false);
 
 var token = undefined;
 
+suite.addBatch({
+  "ping": {
+    topic: wsapi.get('/wsapi/ping', {}),
+    "works when database is unstalled": function(err, r) {
+      // address info with a primary address doesn't need db access.
+      assert.strictEqual(r.code, 200);
+    }
+  }
+});
+
 suite.addBatch({
   "account staging": {
     topic: wsapi.post('/wsapi/stage_user', {
@@ -194,6 +211,13 @@ addStallDriverBatch(true);
 // test remaining wsapis
 
 suite.addBatch({
+  "ping": {
+    topic: wsapi.get('/wsapi/ping', { }),
+    "fails": function(err, r) {
+      assert.strictEqual(r.code, 500);
+    }
+  },
+
   "account_cancel": {
     topic: wsapi.post('/wsapi/account_cancel', { }),
     "fails with 503": function(err, r) {
-- 
GitLab