UNPKG

@bull-board/api

Version:

A Dashboard server API built on top of bull or bullmq.

93 lines 3.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.flowProvider = flowProvider; const bullmq_1 = require("bullmq"); const bullMQ_1 = require("../queueAdapters/bullMQ"); // WeakMap keyed by Redis client so each distinct connection gets its own // FlowProducer, and the entry is automatically freed when the client is GC'd. const flowProducerCache = new WeakMap(); function findBullMQAdapter(queues) { for (const adapter of queues.values()) { if (adapter.type === 'bullmq') { return adapter; } } return null; } async function getFlowProducer(queues) { const adapter = findBullMQAdapter(queues); if (!adapter) return null; const client = await adapter.getClient(); const cached = flowProducerCache.get(client); if (cached) return cached; const producer = new bullmq_1.FlowProducer({ connection: client }); flowProducerCache.set(client, producer); return producer; } /** * Builds a lookup from raw BullMQ queue name to adapter. * Rebuilt on each call to stay consistent with dynamic queue changes. */ function buildQueueNameLookup(queues) { const lookup = new Map(); for (const adapter of queues.values()) { if (adapter.type === 'bullmq') { const bmq = adapter; lookup.set(bmq.getName(), bmq); } } return lookup; } async function getFlowTree(queues, queueName, jobId) { const producer = await getFlowProducer(queues); if (!producer) return null; const flowRoot = await producer.getFlow({ queueName, id: jobId }).catch(() => null); return flowRoot; } function simplifyQueueName(queueName, lookup) { const simpleQueueName = Array.from(lookup.keys()).find(key => queueName === key || queueName.endsWith(':' + key)); return simpleQueueName || queueName; } /** * Traverses the parent chain of a job across queues to find the flow root. * Returns the raw BullMQ queue name and job ID of the root, or null if * no flow root can be determined. */ async function findFlowRoot(queues, job) { var _a; const lookup = buildQueueNameLookup(queues); let currJob = job; while (currJob) { const currQueueName = simplifyQueueName(currJob.queueName, lookup); const parent = (_a = currJob.opts) === null || _a === void 0 ? void 0 : _a.parent; if (!(parent === null || parent === void 0 ? void 0 : parent.id) || !(parent === null || parent === void 0 ? void 0 : parent.queue)) { if (!currJob.id) { return null; } return { queueName: currQueueName, jobId: currJob.id }; } const parentQueueName = parent.queue; const simpleParentQueueName = simplifyQueueName(parentQueueName, lookup); const parentAdapter = simpleParentQueueName ? lookup.get(simpleParentQueueName) : null; if (!parentAdapter) { return null; } const parentJob = await parentAdapter.getJob(parent.id); if (!parentJob) { return null; } currJob = parentJob; } return null; } function flowProvider(next) { return async (req, job, queue) => { const root = queue instanceof bullMQ_1.BullMQAdapter ? await findFlowRoot(req.queues, job) : null; const flowTree = root ? await getFlowTree(req.queues, root.queueName, root.jobId) : null; return next(req, job, queue, flowTree); }; } //# sourceMappingURL=flow.js.map