pushd
Version:
Blazing fast multi-protocol mobile push notification service
155 lines (139 loc) • 4.74 kB
JavaScript
// Generated by CoffeeScript 1.4.0
(function() {
var Event, async, logger,
__hasProp = {}.hasOwnProperty;
async = require('async');
logger = require('winston');
Event = (function() {
Event.prototype.OPTION_IGNORE_MESSAGE = 1;
Event.prototype.name_format = /^[a-zA-Z0-9:._-]{1,100}$/;
function Event(redis, name) {
this.redis = redis;
this.name = name;
if (!(redis != null)) {
throw new Error("Missing redis connection");
}
if (!Event.prototype.name_format.test(this.name)) {
throw new Error('Invalid event name ' + this.name);
}
this.key = "event:" + this.name;
}
Event.prototype.info = function(cb) {
var _this = this;
while (!cb) {
return;
}
return this.redis.multi().hgetall(this.key).zcard("" + this.key + ":subs").exec(function(err, results) {
var f, info, key, num, value, _ref;
if (((function() {
var _ref, _results;
_ref = results[0];
_results = [];
for (f in _ref) {
if (!__hasProp.call(_ref, f)) continue;
_results.push(f);
}
return _results;
})()).length) {
info = {
total: results[1]
};
_ref = results[0];
for (key in _ref) {
if (!__hasProp.call(_ref, key)) continue;
value = _ref[key];
num = parseInt(value);
info[key] = num + '' === value ? num : value;
}
return cb(info);
} else {
return cb(null);
}
});
};
Event.prototype.exists = function(cb) {
var _this = this;
if (this.name === 'broadcast') {
return cb(true);
} else {
return this.redis.sismember("events", this.name, function(err, exists) {
return cb(exists);
});
}
};
Event.prototype["delete"] = function(cb) {
var subscriberCount,
_this = this;
logger.verbose("Deleting event " + this.name);
subscriberCount = 0;
return this.forEachSubscribers(function(subscriber, subOptions, done) {
subscriber.removeSubscription(_this, done);
return subscriberCount += 1;
}, function() {
logger.verbose("Unsubscribed " + subscriberCount + " subscribers from " + _this.name);
return _this.redis.multi().del(_this.key).srem("events", _this.name).exec(function(err, results) {
if (cb) {
return cb(results[1] > 0);
}
});
});
};
Event.prototype.log = function(cb) {
var _this = this;
return this.redis.multi().hincrby(this.key, "total", 1).hset(this.key, "last", Math.round(new Date().getTime() / 1000)).exec(function() {
if (cb) {
return cb();
}
});
};
Event.prototype.forEachSubscribers = function(action, finished) {
var Subscriber, page, perPage, performAction, subscribersKey, total,
_this = this;
Subscriber = require('./subscriber').Subscriber;
if (this.name === 'broadcast') {
performAction = function(subscriberId, subOptions) {
return function(done) {
return action(new Subscriber(_this.redis, subscriberId), {}, done);
};
};
} else {
performAction = function(subscriberId, subOptions) {
var options;
options = {
ignore_message: (subOptions & Event.prototype.OPTION_IGNORE_MESSAGE) !== 0
};
return function(done) {
return action(new Subscriber(_this.redis, subscriberId), options, done);
};
};
}
subscribersKey = this.name === 'broadcast' ? 'subscribers' : "" + this.key + ":subs";
page = 0;
perPage = 100;
total = 0;
return async.whilst(function() {
return page * perPage === total;
}, function(done) {
_this.redis.zrange(subscribersKey, page * perPage, page * perPage + perPage - 1, 'WITHSCORES', function(err, subscriberIdsAndOptions) {
var i, id, tasks, _i, _len, _step;
tasks = [];
for (i = _i = 0, _len = subscriberIdsAndOptions.length, _step = 2; _i < _len; i = _i += _step) {
id = subscriberIdsAndOptions[i];
tasks.push(performAction(id, subscriberIdsAndOptions[i + 1]));
}
return async.series(tasks, function() {
total += subscriberIdsAndOptions.length / 2;
return done();
});
});
return page++;
}, function() {
if (finished) {
return finished(total);
}
});
};
return Event;
})();
exports.Event = Event;
}).call(this);