msgflo
Version:
Polyglot FBP runtime based on message queues
153 lines (144 loc) • 3.8 kB
JavaScript
var clone, uuid;
uuid = require('uuid');
// Based on Underscore.js (MIT)
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
exports.debounce = function(func, wait, immediate) {
var timeout;
timeout = null;
return function() {
var args, callNow, context, later;
context = this;
args = arguments;
later = function() {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
};
callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
func.apply(context, args);
}
};
};
exports.clone = clone = function(obj) {
var flags, key, newInstance;
if ((obj == null) || typeof obj !== 'object') {
return obj;
}
if (obj instanceof Date) {
return new Date(obj.getTime());
}
if (obj instanceof RegExp) {
flags = '';
if (obj.global != null) {
flags += 'g';
}
if (obj.ignoreCase != null) {
flags += 'i';
}
if (obj.multiline != null) {
flags += 'm';
}
if (obj.sticky != null) {
flags += 'y';
}
return new RegExp(obj.source, flags);
}
newInstance = new obj.constructor();
for (key in obj) {
newInstance[key] = clone(obj[key]);
}
return newInstance;
};
exports.readGraph = function(filepath, callback) {
var ext, fbp, fs, path;
path = require('path');
fs = require('fs');
fbp = require('fbp');
ext = path.extname(filepath);
return fs.readFile(filepath, {
encoding: 'utf-8'
}, function(err, contents) {
var e, graph;
if (err) {
return callback(err);
}
try {
if (ext === '.fbp') {
graph = fbp.parse(contents);
} else {
graph = JSON.parse(contents);
}
} catch (error) {
e = error;
return callback(e);
}
return callback(null, graph);
});
};
exports.normalizeOptions = function(options) {
if (!options.broker) {
options.broker = process.env['MSGFLO_BROKER'];
}
if (!options.broker) {
options.broker = process.env['CLOUDAMQP_URL'];
}
if (!options.broker) {
options.broker = 'amqp://localhost';
}
if (!options.runtimeId) {
options.runtimeId = process.env['MSGFLO_RUNTIME_ID'];
}
if (!options.runtimeId) {
options.runtimeId = uuid.v4();
}
if (!options.pingInterval && process.env['MSGFLO_PING_INTERVAL']) {
options.pingInterval = parseInt(process.env['MSGFLO_PING_INTERVAL']);
}
if (!options.pingInterval) { // default: never
options.pingInterval = 0;
}
if (!options.pingMethod) {
options.pingMethod = process.env['MSGFLO_PING_METHOD'];
}
if (!options.pingMethod) {
options.pingMethod = 'POST';
}
if (!options.pingUrl) {
options.pingUrl = process.env['MSGFLO_PING_URL'];
}
if (!options.pingUrl) {
options.pingUrl = "https://api.flowhub.io/runtimes/$RUNTIME_ID";
}
options.pingUrl = options.pingUrl.replace('$RUNTIME_ID', options.runtimeId);
return options;
};
// Note: relies on convention
exports.queueName = function(role, port) {
return `${role}.${port.toUpperCase()}`;
};
exports.isParticipant = function(p) {
return (p.component != null) && p.component !== 'msgflo/RoundRobin' && p.component !== 'msgflo/PubSub';
};
exports.iipsForRole = function(graph, role) {
var conn, i, iips, len, ref;
iips = {};
ref = graph.connections;
for (i = 0, len = ref.length; i < len; i++) {
conn = ref[i];
if (conn.data == null) {
continue;
}
if (conn.tgt.process !== role) {
continue;
}
iips[conn.tgt.port] = conn.data;
}
return iips;
};