UNPKG

@webda/gcp

Version:

Webda GCP Services implementation

133 lines 3.93 kB
import { PubSub } from "@google-cloud/pubsub"; import { CancelablePromise, Queue, QueueParameters } from "@webda/core"; /** * GCPQueue Parameters */ export class GCPQueueParameters extends QueueParameters { } /** * GCP Queue implementation on top of Pub/Sub * * @WebdaModda GoogleCloudQueue */ export default class GCPQueue extends Queue { constructor() { super(...arguments); this.messages = {}; } /** * @override */ loadParameters(params) { return new GCPQueueParameters(params); } /** * @override */ async init() { await super.init(); this.pubsub = new PubSub(); this.projectId = this.pubsub.auth.getProjectId(); return this; } /** * The queue size is not available within this service * * @returns */ async size() { return 0; } /** * Acknowledge a message * @param id */ async deleteMessage(id) { await this.pubsub.auth.request({ method: "POST", url: `https://pubsub.googleapis.com/v1/projects/${await this.projectId}/subscriptions/${this.parameters.subscription}:acknowledge`, body: JSON.stringify({ ackIds: [id] }) }); this.messages[id].ack(); delete this.messages[id]; } /** * Send a message to the queue * @param msg */ async sendMessage(msg) { await this.pubsub.topic(this.parameters.topic).publishMessage({ data: Buffer.from(JSON.stringify(msg)) }); } /** * Retrieve just one message from the queue * @param proto * @returns */ async receiveMessage(proto) { let timeoutId; let errorHandler; let msgHandler; const subscription = this.pubsub.subscription(this.parameters.subscription, { flowControl: { maxMessages: 1 } }); try { return await new Promise((resolve, reject) => { if (this.parameters.timeout) { timeoutId = setTimeout(() => resolve([]), this.parameters.timeout); } errorHandler = err => { reject(err); }; msgHandler = (message) => { this.messages[message.ackId] = message; resolve([ { Message: this.unserialize(message.data.toString(), proto), ReceiptHandle: message.ackId } ]); }; subscription.on("error", errorHandler); subscription.on("message", msgHandler); }); } finally { subscription.close(); if (timeoutId) { clearTimeout(timeoutId); } } } /** * 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) { const subscription = this.pubsub.subscription(this.parameters.subscription, { flowControl: { maxMessages: this.getMaxConsumers() } }); return new CancelablePromise(async () => { subscription.on("message", async (message) => { try { await callback(this.unserialize(message.data.toString(), eventPrototype)); message.ack(); } catch (err) { this.log("ERROR", `Message ${message.ackId}`, err); } }); }, async () => { subscription.close(); }); } } export { GCPQueue }; //# sourceMappingURL=queue.js.map