import cluster from "node:cluster"; import net from "node:net"; import { syncSecrets } from "../security/secrets.js"; import { env, isCluster } from "../config.js"; export { isPrimary, isWorker } from "node:cluster"; export const supportsReusePort = async () => { try { await new Promise((resolve, reject) => { const server = net.createServer().listen({ port: 0, reusePort: true }); server.on('listening', () => server.close(resolve)); server.on('error', (err) => (server.close(), reject(err))); }); return true; } catch { return false; } } export const initCluster = async () => { if (cluster.isPrimary) { for (let i = 1; i < env.instanceCount; ++i) { cluster.fork(); } } await syncSecrets(); } export const broadcast = (message) => { if (!isCluster || !cluster.isPrimary || !cluster.workers) { return; } for (const worker of Object.values(cluster.workers)) { worker.send(message); } } export const send = (message) => { if (!isCluster) { return; } if (cluster.isPrimary) { return broadcast(message); } else { return process.send(message); } } export const waitFor = (key) => { return new Promise(resolve => { const listener = (message) => { if (key in message) { process.off('message', listener); return resolve(message); } } process.on('message', listener); }); } export const mainOnMessage = (cb) => { for (const worker of Object.values(cluster.workers)) { worker.on('message', cb); } }