UNPKG

@eggjs/cluster

Version:

cluster manager for egg

144 lines (142 loc) 3.63 kB
import { debuglog } from "node:util"; import workerThreads from "node:worker_threads"; //#region src/utils/messenger.ts const debug = debuglog("egg/cluster/messenger"); /** * master messenger, provide communication between parent, master, agent and app. * * ┌────────┐ * │ parent │ * /└────────┘\ * / | \ * / ┌────────┐ \ * / │ master │ \ * / └────────┘ \ * / / \ \ * ┌───────┐ ┌───────┐ * │ agent │ ------- │ app │ * └───────┘ └───────┘ * * * in app worker * * ```js * process.send({ * action: 'xxx', * data: '', * to: 'agent/master/parent', // default to agent * }); * ``` * * in agent worker * * ```js * process.send({ * action: 'xxx', * data: '', * to: 'app/master/parent', // default to app * }); * ``` * * in parent * * ```js * process.send({ * action: 'xxx', * data: '', * to: 'app/agent/master', // default to master * }); * ``` */ var Messenger = class { #master; #workerManager; #hasParent; constructor(master, workerManager) { this.#master = master; this.#workerManager = workerManager; this.#hasParent = !!workerThreads.parentPort || !!process.send; process.on("message", (msg) => { msg.from = "parent"; this.send(msg); }); process.once("disconnect", () => { this.#hasParent = false; }); } /** * send message * @param {Object} data message body * - {String} from from who * - {String} to to who */ send(data) { if (!data.from) data.from = "master"; const receiverWorkerId = data.receiverWorkerId ?? data.receiverPid; if (receiverWorkerId) if (receiverWorkerId === String(process.pid)) data.to = "master"; else if (receiverWorkerId === String(this.#workerManager.getAgent().workerId)) data.to = "agent"; else data.to = "app"; if (!data.to) { if (data.from === "agent") data.to = "app"; if (data.from === "app") data.to = "agent"; if (data.from === "parent") data.to = "master"; } if (data.to === "master") { debug("%s -> master, data: %j", data.from, data); this.sendToMaster(data); return; } if (data.to === "parent") { debug("%s -> parent, data: %j", data.from, data); this.sendToParent(data); return; } if (data.to === "app") { debug("%s -> %s, data: %j", data.from, data.to, data); this.sendToAppWorker(data); return; } if (data.to === "agent") { debug("%s -> %s, data: %j", data.from, data.to, data); this.sendToAgentWorker(data); return; } } /** * send message to master self * @param {Object} data message body */ sendToMaster(data) { this.#master.emit(data.action, data.data); } /** * send message to parent process * @param {Object} data message body */ sendToParent(data) { if (!this.#hasParent) return; process.send(data); } /** * send message to app worker * @param {Object} data message body */ sendToAppWorker(data) { for (const worker of this.#workerManager.listWorkers()) { if (worker.state === "disconnected") continue; const receiverWorkerId = data.receiverWorkerId ?? data.receiverPid; if (receiverWorkerId && receiverWorkerId !== String(worker.workerId)) continue; worker.send(data); } } /** * send message to agent worker * @param {Object} data message body */ sendToAgentWorker(data) { const agent = this.#workerManager.getAgent(); if (agent) agent.send(data); } }; //#endregion export { Messenger };