UNPKG

@axinom/mosaic-transactional-inbox-outbox

Version:

This library encapsulates the Mosaic based transactional inbox and outbox pattern

72 lines 3.69 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createMessagingMetric = void 0; const node_crypto_1 = require("node:crypto"); const prom_client_1 = require("prom-client"); const common_1 = require("../common"); const outbox_inbox_health_check_handler_1 = require("./outbox-inbox-health-check-handler"); /** * Creates a `Gauge` metric with the name `ax_messaging` which can be added to a metric registry. * This metric will have an integer value of the duration in seconds if the service can acquire a * service account token, send a message, and afterwards receive it. Or a value of `0` otherwise. * * @param healthCheckRoutingKey The RabbitMQ routing key for sending the outbox message * @param storeOutboxMessage The outbox storage function for starting the message processing * @param getAccessToken Get the access token with admin permissions to include in the message * @param ownerPool The database owner pool as this is independent of an environment * @param timeoutMs The optinal timeout in milliseconds after which the messaging should be considered as failure * @returns A `Gauge` metric with a name `ax_messaging`. */ const createMessagingMetric = (healthCheckRoutingKey, storeOutboxMessage, getAccessToken, ownerPool, timeoutMs = 30000) => { return new prom_client_1.Gauge({ name: `ax_messaging`, help: `Message sending and receiving via RabbitMQ and the transactional outbox and inbox.`, async collect() { const nonce = (0, node_crypto_1.randomUUID)(); const start = Date.now(); const client = await ownerPool.connect(); try { await (0, common_1.awaitWithTimeout)(async () => { await client.query('INSERT INTO app_private.messaging_health (key) VALUES ($1);', [nonce]); await storeOutboxMessage(nonce, (0, outbox_inbox_health_check_handler_1.getServiceHealthCheckMessagingSettings)(healthCheckRoutingKey), { nonce, }, client, { envelopeOverrides: { auth_token: await getAccessToken(), }, }); // no await - stops when the client is released client.query('LISTEN messaging_health_handled;'); let res; const promise = new Promise((resolve) => { res = resolve; }); client.removeAllListeners('notification'); client.on('notification', (data) => { var _a; const payload = JSON.parse((_a = data.payload) !== null && _a !== void 0 ? _a : '{}'); if (payload.key === nonce) { res(payload.success); // set to true or false in the handler } }); const success = await promise; if (success) { this.set(Math.ceil((Date.now() - start) / 1000)); } else { this.set(0); } await client.query('DELETE FROM app_private.messaging_health WHERE key = $1;', [nonce]); }, timeoutMs); client.release(); } catch (error) { this.set(0); client.release(true); return; } }, }); }; exports.createMessagingMetric = createMessagingMetric; //# sourceMappingURL=messaging-health-metrics.js.map