UNPKG

heroku-debug

Version:
209 lines (182 loc) 6.21 kB
'use strict'; var debug = require('debug')('ioredis:connection'); var Command = require('../command'); var utils = require('../utils'); var _ = require('lodash'); exports.connectHandler = function (self) { return function () { self.setStatus('connect'); self.resetCommandQueue(); // AUTH command should be processed before any other commands var flushed = false; if (self.condition.auth) { self.auth(self.condition.auth, function (err) { if (err) { if (err.message.indexOf('no password is set') === -1) { flushed = true; self.flushQueue(err); self.silentEmit('error', err); self.disconnect(true); } else { console.warn('[WARN] Redis server does not require a password, but a password was supplied.'); } } }); } if (self.condition.select) { self.select(self.condition.select); } if (!self.options.enableReadyCheck) { exports.readyHandler(self)(); } self.initParser(); if (self.options.enableReadyCheck) { self._readyCheck(function (err, info) { if (err) { if (!flushed) { self.flushQueue(new Error('Ready check failed: ' + err.message)); self.silentEmit('error', err); self.disconnect(true); } } else { self.serverInfo = info; if (self.connector.check(info)) { exports.readyHandler(self)(); } else { self.disconnect(true); } } }); } }; }; exports.closeHandler = function (self) { return function () { self.setStatus('close'); if (!self.prevCondition) { self.prevCondition = self.condition; } if (self.commandQueue.length) { self.prevCommandQueue = self.commandQueue; } if (self.manuallyClosing) { self.manuallyClosing = false; debug('skip reconnecting since the connection is manually closed.'); return close(); } if (typeof self.options.retryStrategy !== 'function') { debug('skip reconnecting because `retryStrategy` is not a function'); return close(); } var retryDelay = self.options.retryStrategy(++self.retryAttempts); if (typeof retryDelay !== 'number') { debug('skip reconnecting because `retryStrategy` doesn\'t return a number'); return close(); } debug('reconnect in %sms', retryDelay); self.setStatus('reconnecting', retryDelay); self.reconnectTimeout = setTimeout(function () { self.reconnectTimeout = null; self.connect().catch(_.noop); }, retryDelay); }; function close() { self.setStatus('end'); self.flushQueue(new Error(utils.CONNECTION_CLOSED_ERROR_MSG)); } }; exports.dataHandler = function (self) { return function (data) { self.replyParser.execute(data); }; }; exports.errorHandler = function (self) { return function (error) { debug('error: %s', error); self.silentEmit('error', error); }; }; exports.readyHandler = function (self) { return function () { self.setStatus('ready'); self.retryAttempts = 0; if (self.options.monitor) { self.call('monitor'); var sendCommand = self.sendCommand; self.sendCommand = function (command) { if (Command.checkFlag('VALID_IN_MONITOR_MODE', command.name)) { return sendCommand.call(self, command); } command.reject(new Error('Connection is in monitoring mode, can\'t process commands.')); return command.promise; }; self.once('close', function () { delete self.sendCommand; }); self.setStatus('monitoring'); return; } var item; var finalSelect = self.prevCondition ? self.prevCondition.select : self.condition.select; if (self.options.connectionName) { debug('set the connection name [%s]', self.options.connectionName); self.client('setname', self.options.connectionName); } if (self.options.readOnly) { debug('set the connection to readonly mode'); self.readonly().catch(_.noop); } if (self.prevCondition) { var condition = self.prevCondition; self.prevCondition = null; if (condition.subscriber && self.options.autoResubscribe) { // We re-select the previous db first since // `SELECT` command is not valid in sub mode. if (self.condition.select !== finalSelect) { debug('connect to db [%d]', finalSelect); self.select(finalSelect); } var subscribeChannels = condition.subscriber.channels('subscribe'); if (subscribeChannels.length) { debug('subscribe %d channels', subscribeChannels.length); self.subscribe(subscribeChannels); } var psubscribeChannels = condition.subscriber.channels('psubscribe'); if (psubscribeChannels.length) { debug('psubscribe %d channels', psubscribeChannels.length); self.psubscribe(psubscribeChannels); } } } if (self.prevCommandQueue) { if (self.options.autoResendUnfulfilledCommands) { debug('resend %d unfulfilled commands', self.prevCommandQueue.length); while (self.prevCommandQueue.length > 0) { item = self.prevCommandQueue.shift(); if (item.select !== self.condition.select && item.command.name !== 'select') { self.select(item.select); } self.sendCommand(item.command, item.stream); } } else { self.prevCommandQueue = null; } } if (self.offlineQueue.length) { debug('send %d commands in offline queue', self.offlineQueue.length); var offlineQueue = self.offlineQueue; self.resetOfflineQueue(); while (offlineQueue.length > 0) { item = offlineQueue.shift(); if (item.select !== self.condition.select && item.command.name !== 'select') { self.select(item.select); } self.sendCommand(item.command, item.stream); } } if (self.condition.select !== finalSelect) { debug('connect to db [%d]', finalSelect); self.select(finalSelect); } }; };