UNPKG

btrz-sqs

Version:

Betterez simple client to send messages to an AWS SQS queue with a very convenient interface

127 lines (98 loc) 3.13 kB
function SQSWorker(options, fn) { if (!(this instanceof SQSWorker)) return new SQSWorker(options, fn) const AWS = require("@aws-sdk/client-sqs"); this.client = options.client || new AWS.SQS({ credentials: { accessKeyId: options.accessKeyId, secretAccessKey: options.secretAccessKey, }, region: options.region }); // Five seconds more than WaitTimeSeconds // this.client.config.httpOptions.timeout = 25000 this.url = options.url this.parallel = options.parallel || 1 this.timeout = options.timeout || void 0 this.parse = options.parse this.log = options.log || console this.attributes = Array.isArray(options.attributes) ? options.attributes.slice() : [] this.attempts = options.attempts || 3 if (this.attempts && !~this.attributes.indexOf("ApproximateReceiveCount")) { this.attributes.push("ApproximateReceiveCount") } this.fn = fn this.handling = 0 this.receiving = 0 this.maybeMore() } SQSWorker.prototype.maybeMore = function (retries) { if (this.receiving) return if (this.handling >= this.parallel) return this.receiving++ retries = retries || 0 retries++ var self = this var params = { "QueueUrl": this.url , "MaxNumberOfMessages": Math.min(this.parallel, 10) , "VisibilityTimeout": this.timeout , "WaitTimeSeconds": 20 , "AttributeNames": this.attributes } this.client.receiveMessage(params, function (err, data) { self.receiving-- if (err) { self.log.error({ err: err, params: params }, "failed to receive messages") setTimeout(self.maybeMore.bind(self), Math.min(Math.pow(2, retries), 300) * 1000, retries) return } self.log.info({ params: params, response: data }, "receiveMessage response") if (Array.isArray(data.Messages)) { data.Messages.map(self.handleMessage, self) } self.maybeMore() }) } SQSWorker.prototype.handleMessage = function (message) { this.handling++ var payload = message.Body if (this.parse) { try { payload = this.parse(payload) } catch (err) { this.log.error({ err: err, message: message }, "error parsing message body") return } } var self = this if (this.fn.length === 2) { this.fn(payload, callback) } else { this.fn(payload, message, callback) } function callback(err, del) { self.handling-- if (err) { self.log.error({ err: err, message: message, payload: payload }, "error handling message") del = (self.attempts && Number(message["Attributes"]["ApproximateReceiveCount"]) >= self.attempts) } var params = { "QueueUrl": self.url , "ReceiptHandle": message.ReceiptHandle } if (!del) { params["VisibilityTimeout"] = 0 } self.client[del ? "deleteMessage" : "changeMessageVisibility"](params, function (err) { if (err) { self.log.error( { err: err, message: message, payload: payload } , "failed to " + (del ? "delete message" : "change visibility timeout") ) return } self.maybeMore() }) } } module.exports = SQSWorker;