serverless-offline-msk
Version:
A serverless offline plugin that enables AWS MSK events
183 lines (164 loc) • 5.07 kB
JavaScript
/* global define, Promise */
(function (root, factory) {
'use strict';
if (typeof module === 'object' && module.exports && typeof require === 'function') {
// CommonJS
module.exports = factory();
} else if (typeof define === 'function' && typeof define.amd === 'object') {
// AMD. Register as an anonymous module.
define(factory);
} else {
// Browser globals
root.Queue = factory();
}
})
(this, function () {
'use strict';
/**
* @return {Object}
*/
var LocalPromise = typeof Promise !== 'undefined' ? Promise : function () {
return {
then: function () {
throw new Error('Queue.configure() before use Queue');
}
};
};
var noop = function () {};
/**
* @param {*} value
* @returns {LocalPromise}
*/
var resolveWith = function (value) {
if (value && typeof value.then === 'function') {
return value;
}
return new LocalPromise(function (resolve) {
resolve(value);
});
};
/**
* It limits concurrently executed promises
*
* @param {Number} [maxPendingPromises=Infinity] max number of concurrently executed promises
* @param {Number} [maxQueuedPromises=Infinity] max number of queued promises
* @constructor
*
* @example
*
* var queue = new Queue(1);
*
* queue.add(function () {
* // resolve of this promise will resume next request
* return downloadTarballFromGithub(url, file);
* })
* .then(function (file) {
* doStuffWith(file);
* });
*
* queue.add(function () {
* return downloadTarballFromGithub(url, file);
* })
* // This request will be paused
* .then(function (file) {
* doStuffWith(file);
* });
*/
function Queue(maxPendingPromises, maxQueuedPromises, options) {
this.options = options = options || {};
this.pendingPromises = 0;
this.maxPendingPromises = typeof maxPendingPromises !== 'undefined' ? maxPendingPromises : Infinity;
this.maxQueuedPromises = typeof maxQueuedPromises !== 'undefined' ? maxQueuedPromises : Infinity;
this.queue = [];
}
/**
* Defines promise promiseFactory
* @param {Function} GlobalPromise
*/
Queue.configure = function (GlobalPromise) {
LocalPromise = GlobalPromise;
};
/**
* @param {Function} promiseGenerator
* @return {LocalPromise}
*/
Queue.prototype.add = function (promiseGenerator) {
var self = this;
return new LocalPromise(function (resolve, reject, notify) {
// Do not queue to much promises
if (self.queue.length >= self.maxQueuedPromises) {
reject(new Error('Queue limit reached'));
return;
}
// Add to queue
self.queue.push({
promiseGenerator: promiseGenerator,
resolve: resolve,
reject: reject,
notify: notify || noop
});
self._dequeue();
});
};
/**
* Number of simultaneously running promises (which are resolving)
*
* @return {number}
*/
Queue.prototype.getPendingLength = function () {
return this.pendingPromises;
};
/**
* Number of queued promises (which are waiting)
*
* @return {number}
*/
Queue.prototype.getQueueLength = function () {
return this.queue.length;
};
/**
* @returns {boolean} true if first item removed from queue
* @private
*/
Queue.prototype._dequeue = function () {
var self = this;
if (this.pendingPromises >= this.maxPendingPromises) {
return false;
}
// Remove from queue
var item = this.queue.shift();
if (!item) {
if (this.options.onEmpty) {
this.options.onEmpty();
}
return false;
}
try {
this.pendingPromises++;
resolveWith(item.promiseGenerator())
// Forward all stuff
.then(function (value) {
// It is not pending now
self.pendingPromises--;
// It should pass values
item.resolve(value);
self._dequeue();
}, function (err) {
// It is not pending now
self.pendingPromises--;
// It should not mask errors
item.reject(err);
self._dequeue();
}, function (message) {
// It should pass notifications
item.notify(message);
});
} catch (err) {
self.pendingPromises--;
item.reject(err);
self._dequeue();
}
return true;
};
return Queue;
});