UNPKG

redis-spincycle

Version:

library tha connects to a spincycle server using redis pubsub

329 lines (305 loc) 11.4 kB
// Generated by CoffeeScript 1.9.1 (function() { var $q, debug, spinredis, uuid, bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; uuid = require('node-uuid'); $q = require('node-promise'); debug = process.env['DEBUG']; spinredis = (function() { function spinredis(dbUrl) { this.flattenModel = bind(this.flattenModel, this); this.listTargets = bind(this.listTargets, this); this.getModelFor = bind(this.getModelFor, this); this.emitMessage = bind(this.emitMessage, this); this._degisterObjectsSubscriber = bind(this._degisterObjectsSubscriber, this); this.deRegisterObjectsSubscriber = bind(this.deRegisterObjectsSubscriber, this); this.registerObjectsSubscriber = bind(this.registerObjectsSubscriber, this); this.registerObjectsSubscriber = bind(this.registerObjectsSubscriber, this); this.registerListener = bind(this.registerListener, this); this.setup = bind(this.setup, this); this.emit = bind(this.emit, this); var rhost, rport; this.subscribers = []; this.objsubscribers = []; this.objectsSubscribedTo = []; this.outstandingMessages = []; this.modelcache = []; if (debug) { console.log('redis-spincycle dbUrl = ' + dbUrl); } rhost = dbUrl || process.env['REDIS_PORT_6379_TCP_ADDR'] || '127.0.0.1'; rport = process.env['REDIS_PORT_6379_TCP_PORT'] || '6379'; this.sendredis = require('redis').createClient(rport, rhost); this.listenredis = require('redis').createClient(rport, rhost); this.listenredis.on('error', function(err) { return console.log('spinredis listen ERROR: ' + err); }); this.sendredis.on('error', function(err) { return console.log('spinredis send ERROR: ' + err); }); this.sessionId = null; this.objectss = []; this.subscribers['OBJECT_UPDATE'] = [ function(obj) { var k, o, prop, ref, results, v, val; this.subscribers = objsubscribers[obj.id] || []; ref = this.subscribers; results = []; for (k in ref) { v = ref[k]; if (!this.objectss[obj.id]) { this.objectss[obj.id] = obj; } else { o = this.objectss[obj.id]; for (prop in obj) { val = obj[prop]; o[prop] = val; } } results.push(v(obj)); } return results; } ]; this.setup(); } spinredis.prototype.failed = function(msg) { return console.log('spinclient message failed!! ' + msg); }; spinredis.prototype.setSessionId = function(id) { if (id) { console.log('++++++++++++++++++++++++++++++++++++++ spinclient setting session id to ' + id); return this.sessionId = id; } }; spinredis.prototype.dumpOutstanding = function() { console.log('-------------------------------- ' + this.outstandingMessages.length + ' outstanding messages ---------------------------------'); this.outstandingMessages.forEach(function(os) { return console.log(os.messageId + ' -> ' + os.target + ' - ' + os.d); }); return console.log('-----------------------------------------------------------------------------------------'); }; spinredis.prototype.emit = function(message) { message.channelID = 'spinchannel_' + this.channelID; if (debug) { console.log('redisclient emitting message..'); } if (debug) { console.dir(message); } return this.sendredis.publish('spinchannel', JSON.stringify(message)); }; spinredis.prototype.setup = function() { this.channelID = uuid.v4(); this.listenredis.subscribe('spinchannel_' + this.channelID); return this.listenredis.on('message', (function(_this) { return function(channel, replystr) { var detail, i, index, info, message, reply, status; console.log('on message got ' + replystr); reply = JSON.parse(replystr); status = reply.status; message = reply.payload; info = reply.info; console.log('redis-spincycle got reply messageId ' + reply.messageId + ' status ' + status + ', info ' + info + ' data ' + message + ' outstandingMessages = ' + _this.outstandingMessages.length); _this.dumpOutstanding(); index = -1; if (reply.messageId) { i = 0; while (i < _this.outstandingMessages.length) { detail = _this.outstandingMessages[i]; if (detail && detail.messageId === reply.messageId) { if (reply.status === 'FAILURE' || reply.status === 'NOT_ALLOWED') { console.log('spinclient message FAILURE'); console.dir(reply); detail.d.reject(reply); break; } else { detail.d.resolve(message); index = i; break; } } i++; } if (index > -1) { return _this.outstandingMessages.splice(index, 1); } } else { _this.subscribers = _this.subscribers[info]; if (_this.subscribers) { return _this.subscribers.forEach(function(listener) { return listener(message); }); } else { console.log('no subscribers for message ' + message); return console.dir(reply); } } }; })(this)); }; spinredis.prototype.registerListener = function(detail) { console.log('spinclient::registerListener called for ' + detail.message); this.subscribers = this.subscribers[detail.message] || []; this.subscribers.push(detail.callback); return this.subscribers[detail.message] = this.subscribers; }; spinredis.prototype.registerObjectsSubscriber = function(detail) { var d, localsubs, sid; d = $q.defer(); sid = uuid.v4(); localsubs = this.objectsSubscribedTo[detail.id]; console.log('register@objectsSubscriber localsubs is'); console.dir(localsubs); if (!localsubs) { localsubs = []; console.log('no local subs, so get the original server-side subscription for id ' + detail.id); this.registerObjectsSubscriber({ id: detail.id, type: detail.type, cb: function(updatedobj) { var k, lsubs, results, v; console.log('-- register@objectsSubscriber getting obj update callback for ' + detail.id); lsubs = this.objectsSubscribedTo[detail.id]; results = []; for (k in lsubs) { v = lsubs[k]; if (v.cb) { console.log('--*****--*****-- calling back @objects update to local sid --****--*****-- ' + k); results.push(v.cb(updatedobj)); } else { results.push(void 0); } } return results; } }).then((function(_this) { return function(remotesid) { localsubs['remotesid'] = remotesid; localsubs[sid] = detail; console.log('-- adding local callback listener to @objects updates for ' + detail.id + ' local sid = ' + sid + ' remotesid = ' + remotesid); _this.objectsSubscribedTo[detail.id] = localsubs; return d.resolve(sid); }; })(this)); } return d.promise; }; spinredis.prototype.registerObjectsSubscriber = function(detail) { var d; d = $q.defer(); console.log('message-router registering subscriber for @objects ' + detail.id + ' type ' + detail.type); this.subscribers = this.objsubscribers[detail.id] || []; this.emitMessage({ target: 'registerForUpdatesOn', obj: { id: detail.id, type: detail.type } }).then((function(_this) { return function(reply) { console.log('server subscription id for id ' + detail.id + ' is ' + reply); _this.subscribers[reply] = detail.cb; _this.objsubscribers[detail.id] = _this.subscribers; return d.resolve(reply); }; })(this), (function(_this) { return function(reply) { return _this.failed(reply); }; })(this)); return d.promise; }; spinredis.prototype.deRegisterObjectsSubscriber = function(sid, o) { var count, j, k, len, localsubs, v; localsubs = this.objectssSubscribedTo[o.id] || []; if (localsubs[sid]) { console.log('deregistering local updates for @objects ' + o.id); delete localsubs[sid]; count = 0; for (v = j = 0, len = localsubs.length; j < len; v = ++j) { k = localsubs[v]; count++; } if (count === 1) { return this._deRegisterObjectsSubscriber('remotesid', o); } } }; spinredis.prototype._degisterObjectsSubscriber = function(sid, o) { this.subscribers = this.objsubscribers[o.id] || []; if (this.subscribers && this.subscribers[sid]) { delete this.subscribers[sid]; this.objsubscribers[o.id] = this.subscribers; return this.emitMessage({ target: 'deRegisterForUpdatesOn', id: o.id, type: o.type, listenerid: sid }).then(function(reply) { return console.log('deregistering server updates for @objects ' + o.id); }); } }; spinredis.prototype.emitMessage = function(detail) { var d; if (debug) { console.log('emitMessage called'); } d = $q.defer(); detail.messageId = uuid.v4(); detail.sessionId = detail.sessionId || this.sessionId; detail.d = d; this.outstandingMessages.push(detail); if (debug) { console.log('saving outstanding reply to messageId ' + detail.messageId + ' and @sessionId ' + detail.sessionId); } this.emit(detail); return d.promise; }; spinredis.prototype.getModelFor = function(type) { var d; d = $q.defer(); if (this.modelcache[type]) { d.resolve(this.modelcache[type]); } else { this.emitMessage({ target: 'getModelFor', modelname: type }).then(function(model) { this.modelcache[type] = model; return d.resolve(model); }); } return d.promise; }; spinredis.prototype.listTargets = function() { var d; d = $q.defer(); this.emitMessage({ target: 'listcommands' }).then(function(targets) { return d.resolve(targets); }); return d.promise; }; spinredis.prototype.flattenModel = function(model) { var k, rv, v; rv = {}; for (k in model) { v = model[k]; if (angular.isArray(v)) { rv[k] = v.map(function(e) { return e.id; }); } else { rv[k] = v; } } return rv; }; return spinredis; })(); module.exports = spinredis; }).call(this); //# sourceMappingURL=spinredis.js.map