UNPKG

actionhero

Version:

actionhero.js is a multi-transport API Server with integrated cluster capabilities and delayed tasks

155 lines (154 loc) 6.46 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Redis = void 0; const dotProp = require("dot-prop"); const index_1 = require("../index"); /** * Redis helpers and connections. */ class Redis extends index_1.Initializer { constructor() { super(); this.name = "redis"; this.loadPriority = 200; this.startPriority = 101; this.stopPriority = 99999; } async initialize(config) { if (config.redis.enabled === false) { return; } index_1.api.redis = { clients: {}, subscriptionHandlers: {}, rpcCallbacks: {}, status: { subscribed: false, }, }; index_1.api.redis.subscriptionHandlers.do = async (message) => { if (!message.connectionId || (index_1.api.connections && index_1.api.connections.connections[message.connectionId])) { const cmdParts = message.method.split("."); const cmd = cmdParts.shift(); if (cmd !== "api") { throw new Error("cannot operate on a method outside of the api object"); } const callableApi = Object.assign(index_1.api, { log: index_1.log }); const method = dotProp.get(callableApi, cmdParts.join(".")); let args = message.args; if (args === null) { args = []; } if (!Array.isArray(args)) { args = [args]; } if (method) { const response = await method.apply(null, args); await index_1.redis.respondCluster(message.messageId, response); } else { index_1.log("RPC method `" + cmdParts.join(".") + "` not found", "crit"); } } }; index_1.api.redis.subscriptionHandlers.doResponse = function (message) { if (index_1.api.redis.rpcCallbacks[message.messageId]) { const { resolve, timer } = index_1.api.redis.rpcCallbacks[message.messageId]; clearTimeout(timer); resolve(message.response); delete index_1.api.redis.rpcCallbacks[message.messageId]; } }; const connectionNames = ["client", "subscriber", "tasks"]; for (var i in connectionNames) { const r = connectionNames[i]; if (config.redis[r].buildNew === true) { const args = config.redis[r].args; index_1.api.redis.clients[r] = new config.redis[r].konstructor(args[0], args[1], args[2]); index_1.api.redis.clients[r].on("error", (error) => { index_1.log(`Redis connection \`${r}\` error`, "alert", error); }); index_1.api.redis.clients[r].on("connect", () => { index_1.log(`Redis connection \`${r}\` connected`, "debug"); }); index_1.api.redis.clients[r].on("ready", () => { index_1.log(`Redis connection \`${r}\` ready`, "debug"); }); index_1.api.redis.clients[r].on("close", () => { index_1.log(`Redis connection \`${r}\` closed`, "debug"); }); index_1.api.redis.clients[r].on("end", () => { index_1.log(`Redis connection \`${r}\` ended`, "debug"); }); index_1.api.redis.clients[r].on("reconnecting", () => { index_1.log(`Redis connection \`${r}\` reconnecting`, "info"); }); } else { index_1.api.redis.clients[r] = config.redis[r].konstructor.apply(null, config.redis[r].args); index_1.api.redis.clients[r].on("error", (error) => { index_1.log(`Redis connection \`${r}\` error`, "alert", error); }); index_1.log(`Redis connection \`${r}\` connected`, "debug"); } await index_1.api.redis.clients[r].get("_test"); } if (!index_1.api.redis.status.subscribed) { await index_1.api.redis.clients.subscriber.subscribe(config.general.channel); index_1.api.redis.status.subscribed = true; const messageHandler = async (messageChannel, stringifiedMessage) => { let message; try { message = JSON.parse(stringifiedMessage); } catch (e) { message = {}; } if (messageChannel === config.general.channel && message.serverToken === config.general.serverToken) { if (index_1.api.redis.subscriptionHandlers[message.messageType]) { await index_1.api.redis.subscriptionHandlers[message.messageType](message); } } }; index_1.api.redis.clients.subscriber.on("message", messageHandler); } } async start(config) { if (config.redis.enabled === false) { index_1.log("redis is disabled", "notice"); } else { await index_1.redis.doCluster("api.log", [ `actionhero member ${index_1.id} has joined the cluster`, ]); } } async stop(config) { if (config.redis.enabled === false) { return; } await index_1.api.redis.clients.subscriber.unsubscribe(); index_1.api.redis.status.subscribed = false; await index_1.redis.doCluster("api.log", [ `actionhero member ${index_1.id} has left the cluster`, ]); const keys = Object.keys(index_1.api.redis.clients); for (const i in keys) { const client = index_1.api.redis.clients[keys[i]]; if (typeof client.quit === "function") { await client.quit(); //@ts-ignore } else if (typeof client.end === "function") { //@ts-ignore await client.end(); } else if (typeof client.disconnect === "function") { await client.disconnect(); } } } } exports.Redis = Redis;