pipeproc
Version:
Multi-process log processing for nodejs
394 lines (393 loc) • 14.1 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const messages_1 = require("../common/messages");
const process_1 = require("./process");
const path_1 = require("path");
function commit(client, commitLog, callback) {
if (!areValidTopics(commitLog)) {
return callback(new Error("invalid_topic_format"));
}
if (!areValidLogs(commitLog)) {
return callback(new Error("invalid_log_format"));
}
if (client.pipeProcNode) {
const msg = messages_1.prepareLogMessage(messages_1.prepareMessage({ type: "commit" }), commitLog);
client.messageMap[msg.msgKey] = function (e) {
if (e.type === "commit_completed") {
if (e.data && e.data.id) {
callback(null, e.data.id);
}
else {
callback(null, "");
}
}
else if (e.type === "commit_error") {
callback(new Error(e.errStatus || "uknown_error"));
}
};
process_1.sendMessageToNode(client, msg);
}
else {
callback(new Error("no_active_node"));
}
}
exports.commit = commit;
exports.range = function (client, topic, options, callback) {
if (!isValidTopic(topic)) {
return callback(new Error("invalid_topic_format"));
}
if (client.pipeProcNode) {
const msg = messages_1.prepareMessage({ type: "get_range", data: { topic: topic, options: options } });
client.messageMap[msg.msgKey] = function (e) {
if (e.msgKey === msg.msgKey) {
if (e.type === "range_reply") {
try {
const results = e.data.results.map(re => {
return { id: re.id, body: JSON.parse(re.data) };
});
callback(null, results);
}
catch (e) {
callback(new Error("malformed_log"));
}
}
else if (e.type === "range_error") {
callback(new Error(e.errStatus));
}
}
};
process_1.sendMessageToNode(client, msg);
}
else {
callback(new Error("no_active_node"));
}
};
function ack(client, procName, callback) {
if (client.pipeProcNode) {
const msg = messages_1.prepareAckMessage(messages_1.prepareMessage({ type: "ack" }), procName);
client.messageMap[msg.msgKey] = function (e) {
if (e.type === "ack_ok") {
callback(null, e.data.id);
}
else if (e.type === "ack_error") {
callback(new Error(e.errStatus));
}
};
process_1.sendMessageToNode(client, msg);
}
else {
callback(new Error("no_active_node"));
}
}
exports.ack = ack;
function ackCommit(client, procName, commitLog, callback) {
if (!areValidTopics(commitLog)) {
return callback(new Error("invalid_topic_format"));
}
if (!areValidLogs(commitLog)) {
return callback(new Error("invalid_log_format"));
}
if (client.pipeProcNode) {
const msg = messages_1.prepareAckLogMessage(messages_1.prepareMessage({ type: "ack_commit" }), procName, commitLog);
client.messageMap[msg.msgKey] = function (e) {
if (e.type === "ack_commit_completed") {
callback(null, { ackedLogId: e.data.ackedLogId, id: e.data.id });
}
else if (e.type === "ack_commit_error") {
callback(new Error(e.errStatus || "uknown_error"));
}
};
process_1.sendMessageToNode(client, msg);
}
else {
callback(new Error("no_active_node"));
}
}
exports.ackCommit = ackCommit;
function proc(client, topic, options, callback) {
if (client.pipeProcNode) {
if (options.onMaxReclaimsReached !== "disable" && options.onMaxReclaimsReached !== "continue") {
options.onMaxReclaimsReached = "disable";
}
const msg = messages_1.prepareProcMessage(messages_1.prepareMessage({ type: "proc" }), {
topic: topic,
name: options.name,
offset: options.offset,
count: options.count || 1,
maxReclaims: options.maxReclaims || 10,
reclaimTimeout: options.reclaimTimeout || 10000,
onMaxReclaimsReached: options.onMaxReclaimsReached
});
client.messageMap[msg.msgKey] = function (e) {
if (e.type === "proc_ok") {
if (e.data) {
if (Array.isArray(e.data)) {
try {
const results = e.data.map(re => {
return { id: re.id, body: JSON.parse(re.data) };
});
callback(null, results);
}
catch (e) {
callback(new Error("malformed_log"));
}
}
else {
try {
const result = { id: e.data.id, body: JSON.parse(e.data.data) };
callback(null, result);
}
catch (e) {
callback(new Error("malformed_log"));
}
}
}
else {
callback();
}
}
else if (e.type === "proc_error") {
callback(new Error(e.errStatus || "uknown_error"));
}
};
process_1.sendMessageToNode(client, msg);
}
else {
callback(new Error("no_active_node"));
}
}
exports.proc = proc;
function availableProc(client, procList, callback) {
if (!client.pipeProcNode)
return callback(new Error("no_active_node"));
//invalid procs are skipped
const procListWithDefaults = procList
.filter(function (pr) {
return pr.name && pr.topic && pr.offset;
})
.map(function (pr) {
return {
topic: pr.topic,
name: pr.name,
offset: pr.offset,
count: pr.count || 1,
maxReclaims: pr.maxReclaims || 10,
reclaimTimeout: pr.reclaimTimeout || 10000,
onMaxReclaimsReached: pr.onMaxReclaimsReached !== "disable" &&
pr.onMaxReclaimsReached !== "continue" ? "disable" : pr.onMaxReclaimsReached
};
});
const msg = messages_1.prepareAvailableProcMessage(messages_1.prepareMessage({ type: "available_proc" }), procListWithDefaults);
client.messageMap[msg.msgKey] = function (e) {
if (e.type === "available_proc_ok") {
if (!e.data || !e.data.log)
return callback();
if (Array.isArray(e.data.log)) {
try {
const results = e.data.log.map(re => {
return { id: re.id, body: JSON.parse(re.data) };
});
callback(null, { procName: e.data.procName, log: results });
}
catch (e) {
callback(new Error("malformed_log"));
}
}
else {
try {
const result = { id: e.data.log.id, body: JSON.parse(e.data.log.data) };
callback(null, { procName: e.data.procName, log: result });
}
catch (e) {
callback(new Error("malformed_log"));
}
}
}
else {
callback(new Error(e.errStatus || "uknown_error"));
}
};
process_1.sendMessageToNode(client, msg);
}
exports.availableProc = availableProc;
function systemProc(client, options, callback) {
if (client.pipeProcNode) {
if (options.onMaxReclaimsReached !== "disable" && options.onMaxReclaimsReached !== "continue") {
options.onMaxReclaimsReached = "disable";
}
let inlineProcessor;
let externalProcessor;
if (typeof options.processor === "function") {
inlineProcessor = options.processor.toString();
}
else {
externalProcessor = path_1.resolve(options.processor);
}
const msg = messages_1.prepareSystemProcMessage({
name: options.name,
offset: options.offset,
count: options.count || 1,
maxReclaims: options.maxReclaims || 10,
reclaimTimeout: options.reclaimTimeout || 10000,
onMaxReclaimsReached: options.onMaxReclaimsReached,
from: options.from,
to: options.to || "",
inlineProcessor: inlineProcessor,
externalProcessor: externalProcessor
});
if (client.pipeProcNode) {
client.messageMap[msg.msgKey] = function (e) {
if (e.type === "system_proc_ok") {
callback(null, e.data.proc);
}
else if (e.type === "system_proc_error") {
callback(new Error(e.errStatus));
}
};
process_1.sendMessageToNode(client, msg);
}
else {
callback(new Error("no_active_node"));
}
}
}
exports.systemProc = systemProc;
function inspectProc(client, procName, callback) {
if (client.pipeProcNode) {
const msg = messages_1.prepareMessage({ type: "inspect_proc", data: { procName: procName } });
client.messageMap[msg.msgKey] = function (e) {
if (e.type === "inspect_proc_reply") {
callback(null, e.data.proc);
}
else if (e.type === "inspect_proc_error") {
callback(new Error(e.errStatus));
}
};
process_1.sendMessageToNode(client, msg);
}
else {
callback(new Error("no_active_node"));
}
}
exports.inspectProc = inspectProc;
function destroyProc(client, procName, callback) {
if (client.pipeProcNode) {
const msg = messages_1.prepareDestroyProcMessage(messages_1.prepareMessage({ type: "destroy_proc" }), procName);
client.messageMap[msg.msgKey] = function (e) {
if (e.type === "destroy_proc_ok") {
callback(null, e.data.proc);
}
else if (e.type === "destroy_proc_error") {
callback(new Error(e.errStatus || "uknown_error"));
}
};
process_1.sendMessageToNode(client, msg);
}
else {
callback(new Error("no_active_node"));
}
}
exports.destroyProc = destroyProc;
function disableProc(client, procName, callback) {
if (client.pipeProcNode) {
const msg = messages_1.prepareDisableProcMessage(messages_1.prepareMessage({ type: "disable_proc" }), procName);
client.messageMap[msg.msgKey] = function (e) {
if (e.type === "disable_proc_ok") {
callback(null, e.data.proc);
}
else if (e.type === "disable_proc_error") {
callback(new Error(e.errStatus || "uknown_error"));
}
};
process_1.sendMessageToNode(client, msg);
}
else {
callback(new Error("no_active_node"));
}
}
exports.disableProc = disableProc;
function resumeProc(client, procName, callback) {
if (client.pipeProcNode) {
const msg = messages_1.prepareResumeProcMessage(messages_1.prepareMessage({ type: "resume_proc" }), procName);
client.messageMap[msg.msgKey] = function (e) {
if (e.type === "resume_proc_ok") {
callback(null, e.data.proc);
}
else if (e.type === "resume_proc_error") {
callback(new Error(e.errStatus || "uknown_error"));
}
};
process_1.sendMessageToNode(client, msg);
}
else {
callback(new Error("no_active_node"));
}
}
exports.resumeProc = resumeProc;
function reclaimProc(client, procName, callback) {
if (client.pipeProcNode) {
const msg = messages_1.prepareReclaimProcMessage(messages_1.prepareMessage({ type: "reclaim_proc" }), procName);
client.messageMap[msg.msgKey] = function (e) {
if (e.type === "reclaim_proc_ok") {
callback(null, e.data.lastClaimedRange);
}
else if (e.type === "reclaim_proc_error") {
callback(new Error(e.errStatus || "uknown_error"));
}
};
process_1.sendMessageToNode(client, msg);
}
else {
callback(new Error("no_active_node"));
}
}
exports.reclaimProc = reclaimProc;
function waitForProcs(client, procFilter, callback) {
if (client.pipeProcNode) {
const msg = messages_1.prepareMessage({ type: "wait_for_procs", data: { procs: procFilter } });
client.messageMap[msg.msgKey] = function () {
callback();
};
process_1.sendMessageToNode(client, msg);
}
else {
callback(new Error("no_active_node"));
}
}
exports.waitForProcs = waitForProcs;
function areValidTopics(commitLog) {
if (Array.isArray(commitLog)) {
return commitLog.filter(l => {
return isValidTopic(l.topic);
}).length === commitLog.length;
}
else {
return isValidTopic(commitLog.topic);
}
}
function isValidTopic(topic) {
if (topic && typeof topic === "string" && topic.match(/^[a-zA-Z0-9_-]+$/)) {
return true;
}
else {
return false;
}
}
function areValidLogs(commitLog) {
if (Array.isArray(commitLog)) {
return commitLog.filter(l => {
return isValidLog(l.body);
}).length === commitLog.length;
}
else {
return isValidLog(commitLog.body);
}
}
function isValidLog(log) {
if (log && typeof log === "object") {
return true;
}
else {
return false;
}
}
;