From cf283895369412c1bfd7fdcda981f47a3c1bd4d0 Mon Sep 17 00:00:00 2001 From: Lloyd Hilaiel Date: Tue, 22 May 2012 17:53:05 -0600 Subject: [PATCH] db.ping() must use the same application level query timing and reconnection logic as other query types - issue #1608 --- lib/db/mysql_wrapper.js | 63 ++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/lib/db/mysql_wrapper.js b/lib/db/mysql_wrapper.js index 45edfd7de..931ff97fb 100644 --- a/lib/db/mysql_wrapper.js +++ b/lib/db/mysql_wrapper.js @@ -39,14 +39,15 @@ exports.createClient = function(options) { logger.warn("database connection down: " + e.toString()); }); }, - ping: function(cb) { - if (stalled) { - process.nextTick(function() { - cb("database is intentionally stalled"); - }); - } else { - this.realClient.ping(cb); - } + ping: function(client_cb) { + // ping queries are added to the front of the pending work queue. they are + // a priority, as they are used by load balancers that want to know the health + // of the system. + queryQueue.unshift({ + ping: true, + cb: client_cb + }); + this._runNextQuery(); }, _runNextQuery: function() { var self = this; @@ -93,25 +94,41 @@ exports.createClient = function(options) { } }, config.get('database.max_query_time_ms')); - this.realClient.query(work.query, work.args, function(err, r) { - // if we want to simulate a "stalled" mysql connection, we simply - // ignore the results from a query. - if (stalled) return; + if (work.ping) { + this.realClient.ping(function(err) { + if (stalled) { + return invokeCallback(work.cb, "database is intentionally stalled"); + } - clearTimeout(slowQueryTimer); - slowQueryTimer = null; - consecutiveFailures = 0; + clearTimeout(slowQueryTimer); + slowQueryTimer = null; + consecutiveFailures = 0; - // report query time for all queries via statsd - var reqTime = new Date - work.startTime; - statsd.timing('query_time', reqTime); + invokeCallback(work.cb, err); - // report failed queries via statsd - if (err) statsd.increment('failed_query'); + self._runNextQuery(); + }); + } else { + this.realClient.query(work.query, work.args, function(err, r) { + // if we want to simulate a "stalled" mysql connection, we simply + // ignore the results from a query. + if (stalled) return; - invokeCallback(work.cb, err, r); - self._runNextQuery(); - }); + clearTimeout(slowQueryTimer); + slowQueryTimer = null; + consecutiveFailures = 0; + + // report query time for all queries via statsd + var reqTime = new Date - work.startTime; + statsd.timing('query_time', reqTime); + + // report failed queries via statsd + if (err) statsd.increment('failed_query'); + + invokeCallback(work.cb, err, r); + self._runNextQuery(); + }); + } }, query: function() { var client_cb;