Files
talk/services/redis.js
T
2017-08-18 11:50:51 -06:00

101 lines
2.5 KiB
JavaScript

const redis = require('redis');
const debug = require('debug')('talk:services:redis');
const enabled = require('debug').enabled('talk:services:redis');
const {
REDIS_URL,
REDIS_RECONNECTION_MAX_ATTEMPTS,
REDIS_RECONNECTION_MAX_RETRY_TIME,
REDIS_RECONNECTION_BACKOFF_FACTOR,
REDIS_RECONNECTION_BACKOFF_MINIMUM_TIME,
} = require('../config');
const attachMonitors = (client) => {
debug('client created');
// Debug events.
if (enabled) {
client.on('ready', () => debug('client ready'));
client.on('connect', () => debug('client connected'));
client.on('reconnecting', () => debug('client connection lost, attempting to reconnect'));
client.on('end', () => debug('client ended'));
}
// Error events.
client.on('error', (err) => {
if (err) {
console.error('Error connecting to redis:', err);
}
});
};
const connectionOptions = {
url: REDIS_URL,
retry_strategy: function(options) {
if (options.error && options.error.code !== 'ECONNREFUSED') {
debug('retry strategy: none, an error occured');
// End reconnecting on a specific error and flush all commands with a individual error
return options.error;
}
if (options.total_retry_time > REDIS_RECONNECTION_MAX_RETRY_TIME) {
debug('retry strategy: none, exhausted retry time');
// End reconnecting after a specific timeout and flush all commands with a individual error
return new Error('Retry time exhausted');
}
if (options.attempt > REDIS_RECONNECTION_MAX_ATTEMPTS) {
debug('retry strategy: none, exhausted retry attempts');
// End reconnecting with built in error
return undefined;
}
// reconnect after
const delay = Math.max(options.attempt * REDIS_RECONNECTION_BACKOFF_FACTOR, REDIS_RECONNECTION_BACKOFF_MINIMUM_TIME);
debug(`retry strategy: try to reconnect ${delay} ms from now`);
return delay;
}
};
const createClient = () => {
let client = redis.createClient(connectionOptions);
// Attach the monitors that will print debug messages to the console.
attachMonitors(client);
client.ping((err) => {
if (err) {
console.error('Can\'t ping the redis server!');
throw err;
}
});
return client;
};
module.exports = {
connectionOptions,
attachMonitors,
createClient,
createClientFactory: () => {
let client = null;
return () => {
if (client !== null) {
return client;
}
client = createClient();
return client;
};
}
};