UNPKG

joola.io.engine

Version:
196 lines (179 loc) 6.54 kB
/** * joola.io * * Copyright Joola Smart Solutions, Ltd. <info@joo.la> * * Licensed under GNU General Public License 3.0 or later. * Some rights reserved. See LICENSE, AUTHORS. * * @license GPL-3.0+ <http://spdx.org/licenses/GPL-3.0+> */ var redis = function (joola, next) { joola.redis = {}; joola.redis.online = false; joola.redis.fake = joola.config.server.redis.fake; joola.redis.pingTime = 1000; joola.redis.lostPeerCheckTime = 5000; if (joola.config.server.redis.DB == null) { joola.config.server.redis.DB = 0; } joola.redis.channelHandlers = {}; var redisPackage; if (joola.redis.fake == true) { joola.info("running with fakeredis", "warning"); redisPackage = require('fakeredis'); redisPackage.fast = true; } else { redisPackage = require('redis'); } joola.redis._start = function (joola, next) { joola.redis.ping(function () { joola.redis.checkForDroppedPeers(function () { next(); }); }); }; joola.redis._teardown = function (joola, next) { joola.redis.stopTimers(joola); joola.redis.client.lrem("joola:peers", 1, joola.id, function (err, count) { if (count != 1) { joola.logger.error("Error removing myself from the peers list"); } joola.redis.client.hdel("joola:peerPings", joola.id, function () { next(); }); }); }; joola.redis.initialize = function (callback) { var started = 0; ['client', 'client-subscriber'].forEach(function (client) { started++; joola.redis[client] = redisPackage.createClient(joola.config.server.redis.port, joola.config.server.redis.host, joola.config.server.redis.options || {}); joola.redis[client].on("error", function (err) { joola.logger.error("Redis Error: " + err); joola.redis.online = false; //return callback(err); //process.exit(); // redis is really important... }); joola.redis[client].on("connect", function (err) { if (err) return callback(err); joola.logger.silly("client connected to redis [" + client + "] @ " + joola.config.server.redis.host + ":" + joola.config.server.redis.port + " on DB #" + joola.config.server.redis.DB); joola.redis.online = true; }); if (joola.config.server.redis.password != null) { joola.redis[client].auth(joola.config.server.redis.password, function () { joola.redis[client].select(joola.config.server.redis.DB, function (err) { if (err) { //joola.logger.error("Error selecting DB #" + joola.config.server.redis.DB + " on redis."); return callback(new Error('Failed to select DB #' + joola.config.server.redis.DB + " on redis: " + err)); } started--; if (started == 0) { joola.redis.initPeers(callback); } }); }); } else if (joola.config.server.redis.fake != true) { process.nextTick(function () { joola.redis[client].select(joola.config.server.redis.DB, function (err) { if (err) { //joola.logger.error("Error selecting DB #" + joola.config.server.redis.DB + " on redis."); return callback(new Error('Failed to select DB #' + joola.config.server.redis.DB + " on redis: " + err)); } started--; if (started == 0) { joola.redis.initPeers(callback); } }); }); } else { process.nextTick(function () { started--; if (started == 0) { joola.redis.initPeers(callback); } }); } }); }; joola.redis.initPeers = function (callback) { var successMessage = "connected to redis @ " + joola.config.server.redis.host + ":" + joola.config.server.redis.port + " on DB #" + joola.config.server.redis.DB; if (joola.redis.fake != true) { joola.redis.client.lrem("joola:peers", 1, joola.id, function () { joola.redis.client.rpush("joola:peers", joola.id, function () { joola.logger.info(successMessage); joola.redis.online = true; return callback(); }); }); } else { joola.redis.client.rpush("joola:peers", joola.id, function () { process.nextTick(function () { joola.logger.info(successMessage); joola.redis.online = true; return callback(); }); }); } }; joola.redis.stopTimers = function (joola) { clearTimeout(joola.redis.pingTimer); clearTimeout(joola.redis.lostPeerTimer); }; joola.redis.ping = function (next) { clearTimeout(joola.redis.pingTimer); joola.redis.client.hset("joola:peerPings", joola.id, new Date().getTime(), function () { if (joola.running) { joola.redis.pingTimer = setTimeout(joola.redis.ping, joola.redis.pingTime, joola); } if (typeof next == "function") { next(); } }); }; joola.redis.checkForDroppedPeers = function (next) { clearTimeout(joola.redis.lostPeerTimer); var allowedOffset = ( joola.redis.pingTime * 2 ) + 1; joola.redis.client.hgetall("joola:peerPings", function (err, peerPings) { var peerID = null; for (var i in peerPings) { if (peerPings.hasOwnProperty(i)) { if (new Date().getTime() - parseInt(peerPings[i]) > allowedOffset) { peerID = i; break; // do one at a time } } } if (peerID != null) { joola.logger.error("peer: " + peerID + " has gone away"); joola.redis.client.hdel("joola:peerPings", peerID, function () { joola.redis.client.lrem("joola:peers", 1, peerID, function () { if (joola.running) { joola.redis.lostPeerTimer = setTimeout(joola.redis.checkForDroppedPeers, joola.redis.lostPeerCheckTime, joola); } if (typeof next == "function") { next(); } }); }); } else { joola.redis.lostPeerTimer = setTimeout(joola.redis.checkForDroppedPeers, joola.redis.lostPeerCheckTime, joola); if (typeof next == "function") { next(); } } }); }; joola.redis.flushdb = function (next) { joola.redis.client.flushdb(function (err) { next(err); }); }; joola.redis.initialize(function () { next(); }); }; ///////////////////////////////////////////////////////////////////// // exports exports.redis = redis;