UNPKG

@webda/amqp

Version:

Implements AMQP on webda

95 lines 3.31 kB
import { CancelablePromise, JSONUtils, PubSubService, ServiceParameters } from "@webda/core"; import * as amqplib from "amqplib"; export class AMQPPubSubParameters extends ServiceParameters { constructor(params) { var _a; super(params); this.exchange ?? (this.exchange = {}); (_a = this.exchange).type ?? (_a.type = "fanout"); this.subscription ?? (this.subscription = ""); } } /** * * @see https://www.rabbitmq.com/tutorials/tutorial-three-python.html * @WebdaModda AMQPPubSub */ export default class AMQPPubSubService extends PubSubService { /** * @override */ loadParameters(params) { return new AMQPPubSubParameters(params); } /** * @override */ async sendMessage(event, routingKey = "") { this.metrics.messages_sent.inc(); await this.channel.publish(this.parameters.channel, routingKey, Buffer.from(JSONUtils.stringify(event))); } /** * @override */ async init() { await super.init(); this.conn = await amqplib.connect(this.parameters.url); this.channel = await this.conn.createChannel(); let params = { ...this.parameters.exchange }; delete params.type; this.exchange = await this.channel.assertExchange(this.parameters.channel, this.parameters.exchange?.type || "fanout", params); return this; } /** * Return queue size * @returns */ async size() { return (await this.channel.assertQueue(this.parameters.subscription)).messageCount; } /** * Work a queue calling the callback with every Event received * If the callback is called without exception the `deleteMessage` is called * @param callback * @param eventPrototype */ consume(callback, eventPrototype, onBind) { let consumerTag; return new CancelablePromise(async (_resolve, reject) => { let queue = await this.channel.assertQueue(this.parameters.subscription, { exclusive: true, durable: false, autoDelete: true }); await this.channel.bindQueue(queue.queue, this.parameters.channel, "*"); consumerTag = (await this.channel.consume(queue.queue, async (msg) => { if (msg === null) { reject("Cancelled by server"); return; } this.metrics.messages_received.inc(); const end = this.metrics.processing_duration.startTimer(); try { await callback(this.unserialize(msg?.content.toString() || "", eventPrototype)); await this.channel.ack(msg); } catch (err) { this.metrics.errors.inc(); this.getWebda().log("ERROR", `Message ${msg?.properties?.messageId}`, err); } finally { end(); } })).consumerTag; if (onBind) { onBind(); } }, async () => { if (consumerTag) { this.channel.cancel(consumerTag); } }); } } export { AMQPPubSubService }; //# sourceMappingURL=pubsub.js.map