UNPKG

pipeproc

Version:

Multi-process log processing for nodejs

394 lines (393 loc) 14.1 kB
"use strict"; 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; } }