the-shepherd
Version:
Control a herd of wild processes.
203 lines (185 loc) • 6.17 kB
JavaScript
// Generated by CoffeeScript 1.8.0
(function() {
var $, Opts, Rabbit, RabbitJS, chan, log, rabbit, ready, url, verbose,
__slice = [].slice,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
$ = require("bling");
RabbitJS = require('rabbit.js');
Opts = require('./opts');
log = $.logger("[rabbit]");
verbose = function() {
var a;
a = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
if (Opts.verbose) {
return log.apply(null, a);
}
};
ready = $.Promise();
Rabbit = (function(_super) {
__extends(Rabbit, _super);
function Rabbit() {
Rabbit.__super__.constructor.call(this, this);
}
Rabbit.prototype.connect = function(url) {
var context;
if (this.resolved || this.rejected) {
this.reconnect(url);
}
verbose("Connecting to...", url);
context = RabbitJS.createContext(url);
context._sockets = Object.create(null);
context._patterns = Object.create(null);
context._url = url;
context.on("ready", (function(_this) {
return function() {
var connected_to;
verbose("Connected.");
connected_to = url;
return _this.resolve(context);
};
})(this));
context.on("error", (function(_this) {
return function(err) {
log("Failed to connect to", url, err);
return _this.reject(err);
};
})(this));
return this;
};
Rabbit.prototype.reconnect = function(url) {
if (!(this.resolved || this.rejected)) {
return this.connect(url);
} else {
return this.wait((function(_this) {
return function(err, context) {
var args, chan, list, _i, _len, _ref;
_this.reset();
verbose("Reconnecting...", url);
if (context) {
_ref = context._patterns;
for (chan in _ref) {
list = _ref[chan];
for (_i = 0, _len = list.length; _i < _len; _i++) {
args = list[_i];
verbose("Re-subscribing...", chan, args.p);
_this.subscribe(chan, args.p, args.h);
}
}
}
return _this.connect(url);
};
})(this));
}
};
Rabbit.prototype.publish = function(chan, msg) {
var p;
if (arguments.length < 2 || (!$.is('string', chan))) {
throw new Error("Invalid arguments to publish 0: " + (String(chan)) + " 1: " + (String(msg)));
}
try {
return p = $.Promise();
} finally {
this.then(function(context) {
var pub;
pub = context.socket('PUB');
return pub.connect(chan, function() {
pub.write(JSON.stringify(msg), 'utf8');
pub.close();
return p.resolve();
});
});
}
};
Rabbit.prototype.subscribe = function(c, p, h) {
var _ref, _ref1;
if ($.is('function', c)) {
_ref = [c, null, rabbitChannel()], h = _ref[0], p = _ref[1], c = _ref[2];
} else if ($.is('function', p)) {
_ref1 = [p, null], h = _ref1[0], p = _ref1[1];
}
if (p == null) {
p = $.matches.Any;
}
return this.then(function(context) {
var args, onData, sub;
verbose("adding rabbit subscription:", c, $.toRepr(p));
if (typeof err !== "undefined" && err !== null) {
return log("error:", err);
}
sub = context._sockets[c];
args = {
p: p,
h: h
};
onData = null;
if (sub != null) {
context._patterns[c].push(args);
return verbose("subscribed to channel", c, p);
} else {
context._patterns[c] = [args];
context._sockets[c] = sub = context.socket('SUB');
sub.on('data', onData = function(data) {
var err, _i, _len, _ref2, _results;
try {
data = JSON.parse(data);
} catch (_error) {
err = _error;
return log("JSON.parse error:", err.message, "in", data);
}
_ref2 = context._patterns[c];
_results = [];
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
args = _ref2[_i];
if ($.matches(args.p, data)) {
try {
_results.push(args.h(data));
} catch (_error) {
err = _error;
_results.push(log("error in handler:", err.stack));
}
}
}
return _results;
});
sub.on('drain', onData);
return sub.connect(c, function() {
return verbose("subscribed to channel", c, p);
});
}
});
};
return Rabbit;
})($.Promise);
$.extend(module.exports, new Rabbit());
if (require.main === module) {
rabbit = new Rabbit();
url = $.config.get("AMQP_URL", "amqp://test:test@130.211.112.10:5672");
chan = $.config.get("AMQP_CHANNEL", "test");
rabbit.connect(url).then(function() {
rabbit.subscribe(chan, function(m) {
return console.log("(" + ($.now - m.ts) + "ms)->:", m);
});
return $.delay(100, function() {
log("publishing...");
return rabbit.publish(chan, {
op: "ping",
ts: $.now
}).then(function() {
return $.delay(100, function() {
return rabbit.reconnect(url).then(function() {
return rabbit.publish(chan, {
op: "ping",
ts: $.now
}).then(function() {
return $.delay(100, function() {
return process.exit(0);
});
});
});
});
});
});
});
}
}).call(this);