Files
talk/services/redis.js
T
2018-04-09 13:59:23 -06:00

95 lines
2.2 KiB
JavaScript

const Redis = require('ioredis');
const merge = require('lodash/merge');
const {
REDIS_URL,
REDIS_RECONNECTION_BACKOFF_FACTOR,
REDIS_RECONNECTION_BACKOFF_MINIMUM_TIME,
REDIS_CLIENT_CONFIG,
REDIS_CLUSTER_MODE,
REDIS_CLUSTER_CONFIGURATION,
LOGGING_LEVEL,
} = require('../config');
const { createLogger } = require('./logging');
const logger = createLogger('redis');
const attachMonitors = client => {
logger.debug('client created');
// Debug events.
if (['debug', 'trace'].includes(LOGGING_LEVEL)) {
client.on('connect', () => logger.info('client connected'));
client.on('ready', () => logger.debug('client ready'));
client.on('close', () => logger.debug('client closed the connection'));
client.on('reconnecting', () =>
logger.debug('client connection lost, attempting to reconnect')
);
client.on('end', () => logger.debug('client ended'));
}
// Error events.
client.on('error', err => {
if (err) {
logger.error({ err }, 'cannot connect to redis');
}
});
client.on('node error', err => logger.error({ err }, 'node error'));
};
function retryStrategy(times) {
const delay = Math.max(
times * REDIS_RECONNECTION_BACKOFF_FACTOR,
REDIS_RECONNECTION_BACKOFF_MINIMUM_TIME
);
logger.debug(`retry strategy: try to reconnect ${delay} ms from now`);
return delay;
}
const createClient = () => {
let client;
if (REDIS_CLUSTER_MODE === 'NONE') {
client = new Redis(
REDIS_URL,
merge({}, REDIS_CLIENT_CONFIG, {
retryStrategy,
})
);
} else if (REDIS_CLUSTER_MODE === 'CLUSTER') {
client = new Redis.Cluster(
REDIS_CLUSTER_CONFIGURATION,
merge(
{
scaleReads: 'slave',
},
REDIS_CLIENT_CONFIG,
{
clusterRetryStrategy: retryStrategy,
}
)
);
}
// Attach the monitors that will print debug messages to the console.
attachMonitors(client);
return client;
};
module.exports = {
createClient,
createClientFactory: () => {
let client = null;
return () => {
if (client !== null) {
return client;
}
client = createClient();
return client;
};
},
};