bottleneck
Advanced tools
Comparing version 2.12.2 to 2.13.0
{ | ||
"name": "bottleneck", | ||
"main": "bottleneck.js", | ||
"version": "2.12.2", | ||
"version": "2.13.0", | ||
"homepage": "https://github.com/SGrondin/bottleneck", | ||
@@ -6,0 +6,0 @@ "authors": [ |
"use strict"; | ||
(function () { | ||
var Batcher, Events, parser; | ||
var Batcher, Events, parser; | ||
parser = require("./parser"); | ||
Events = require("./Events"); | ||
parser = require("./parser"); | ||
Batcher = function () { | ||
class Batcher { | ||
constructor(options = {}) { | ||
this.options = options; | ||
parser.load(this.options, this.defaults, this); | ||
this.Events = new Events(this); | ||
this._arr = []; | ||
Events = require("./Events"); | ||
this._resetPromise(); | ||
Batcher = function () { | ||
class Batcher { | ||
constructor(options = {}) { | ||
this.options = options; | ||
parser.load(this.options, this.defaults, this); | ||
this.Events = new Events(this); | ||
this._arr = []; | ||
this._resetPromise(); | ||
this._lastFlush = Date.now(); | ||
} | ||
this._lastFlush = Date.now(); | ||
} | ||
_resetPromise() { | ||
return this._promise = new this.Promise((res, rej) => { | ||
return this._resolve = res; | ||
}); | ||
} | ||
_resetPromise() { | ||
return this._promise = new this.Promise((res, rej) => { | ||
return this._resolve = res; | ||
}); | ||
} | ||
_flush() { | ||
clearTimeout(this._timeout); | ||
this._lastFlush = Date.now(); | ||
this._resolve(); | ||
this.Events.trigger("batch", [this._arr]); | ||
this._arr = []; | ||
return this._resetPromise(); | ||
} | ||
_flush() { | ||
clearTimeout(this._timeout); | ||
this._lastFlush = Date.now(); | ||
add(data) { | ||
var ret; | ||
this._arr.push(data); | ||
ret = this._promise; | ||
if (this._arr.length === this.maxSize) { | ||
this._flush(); | ||
} else if (this.maxTime != null && this._arr.length === 1) { | ||
this._timeout = setTimeout(() => { | ||
return this._flush(); | ||
}, this.maxTime); | ||
} | ||
return ret; | ||
this._resolve(); | ||
this.Events.trigger("batch", [this._arr]); | ||
this._arr = []; | ||
return this._resetPromise(); | ||
} | ||
add(data) { | ||
var ret; | ||
this._arr.push(data); | ||
ret = this._promise; | ||
if (this._arr.length === this.maxSize) { | ||
this._flush(); | ||
} else if (this.maxTime != null && this._arr.length === 1) { | ||
this._timeout = setTimeout(() => { | ||
return this._flush(); | ||
}, this.maxTime); | ||
} | ||
}; | ||
return ret; | ||
} | ||
Batcher.prototype.defaults = { | ||
maxTime: null, | ||
maxSize: null, | ||
Promise: Promise | ||
}; | ||
} | ||
return Batcher; | ||
}.call(this); | ||
; | ||
Batcher.prototype.defaults = { | ||
maxTime: null, | ||
maxSize: null, | ||
Promise: Promise | ||
}; | ||
return Batcher; | ||
}.call(void 0); | ||
module.exports = Batcher; | ||
}).call(undefined); | ||
module.exports = Batcher; |
"use strict"; | ||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); | ||
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } | ||
function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } | ||
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } | ||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } | ||
function _toArray(arr) { return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest(); } | ||
(function () { | ||
var Bottleneck, | ||
DEFAULT_PRIORITY, | ||
Events, | ||
LocalDatastore, | ||
NUM_PRIORITIES, | ||
Queues, | ||
RedisDatastore, | ||
States, | ||
Sync, | ||
packagejson, | ||
parser, | ||
splice = [].splice; | ||
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } | ||
NUM_PRIORITIES = 10; | ||
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } | ||
DEFAULT_PRIORITY = 5; | ||
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } | ||
parser = require("./parser"); | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } | ||
Queues = require("./Queues"); | ||
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } | ||
LocalDatastore = require("./LocalDatastore"); | ||
var Bottleneck, | ||
DEFAULT_PRIORITY, | ||
Events, | ||
LocalDatastore, | ||
NUM_PRIORITIES, | ||
Queues, | ||
RedisDatastore, | ||
States, | ||
Sync, | ||
packagejson, | ||
parser, | ||
splice = [].splice; | ||
NUM_PRIORITIES = 10; | ||
DEFAULT_PRIORITY = 5; | ||
parser = require("./parser"); | ||
Queues = require("./Queues"); | ||
LocalDatastore = require("./LocalDatastore"); | ||
RedisDatastore = require("./RedisDatastore"); | ||
Events = require("./Events"); | ||
States = require("./States"); | ||
Sync = require("./Sync"); | ||
packagejson = require("../package.json"); | ||
RedisDatastore = require("./RedisDatastore"); | ||
Bottleneck = function () { | ||
class Bottleneck { | ||
constructor(options = {}, ...invalid) { | ||
var storeInstanceOptions, storeOptions; | ||
this._drainOne = this._drainOne.bind(this); | ||
this.submit = this.submit.bind(this); | ||
this.schedule = this.schedule.bind(this); | ||
this.updateSettings = this.updateSettings.bind(this); | ||
this.incrementReservoir = this.incrementReservoir.bind(this); | ||
Events = require("./Events"); | ||
this._validateOptions(options, invalid); | ||
States = require("./States"); | ||
parser.load(options, this.instanceDefaults, this); | ||
this._queues = new Queues(NUM_PRIORITIES); | ||
this._scheduled = {}; | ||
this._states = new States(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); | ||
this._limiter = null; | ||
this.Events = new Events(this); | ||
this._submitLock = new Sync("submit", this); | ||
this._registerLock = new Sync("register", this); | ||
storeOptions = parser.load(options, this.storeDefaults, {}); | ||
Sync = require("./Sync"); | ||
this._store = function () { | ||
if (this.datastore === "redis" || this.datastore === "ioredis" || this.connection != null) { | ||
storeInstanceOptions = parser.load(options, this.redisStoreDefaults, {}); | ||
return new RedisDatastore(this, storeOptions, storeInstanceOptions); | ||
} else if (this.datastore === "local") { | ||
storeInstanceOptions = parser.load(options, this.localStoreDefaults, {}); | ||
return new LocalDatastore(this, storeOptions, storeInstanceOptions); | ||
} else { | ||
throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); | ||
} | ||
}.call(this); | ||
packagejson = require("../package.json"); | ||
this._queues.on("leftzero", () => { | ||
var base; | ||
return typeof (base = this._store.heartbeat).ref === "function" ? base.ref() : void 0; | ||
}); | ||
Bottleneck = function () { | ||
class Bottleneck { | ||
constructor(options = {}, ...invalid) { | ||
var storeInstanceOptions, storeOptions; | ||
this._drainOne = this._drainOne.bind(this); | ||
this.submit = this.submit.bind(this); | ||
this.schedule = this.schedule.bind(this); | ||
this.updateSettings = this.updateSettings.bind(this); | ||
this.incrementReservoir = this.incrementReservoir.bind(this); | ||
this._validateOptions(options, invalid); | ||
parser.load(options, this.instanceDefaults, this); | ||
this._queues = new Queues(NUM_PRIORITIES); | ||
this._scheduled = {}; | ||
this._states = new States(["RECEIVED", "QUEUED", "RUNNING", "EXECUTING"].concat(this.trackDoneStatus ? ["DONE"] : [])); | ||
this._limiter = null; | ||
this.Events = new Events(this); | ||
this._submitLock = new Sync("submit", this); | ||
this._registerLock = new Sync("register", this); | ||
storeOptions = parser.load(options, this.storeDefaults, {}); | ||
this._store = function () { | ||
if (this.datastore === "redis" || this.datastore === "ioredis" || this.connection != null) { | ||
storeInstanceOptions = parser.load(options, this.redisStoreDefaults, {}); | ||
return new RedisDatastore(this, storeOptions, storeInstanceOptions); | ||
} else if (this.datastore === "local") { | ||
storeInstanceOptions = parser.load(options, this.localStoreDefaults, {}); | ||
return new LocalDatastore(this, storeOptions, storeInstanceOptions); | ||
} else { | ||
throw new Bottleneck.prototype.BottleneckError(`Invalid datastore type: ${this.datastore}`); | ||
} | ||
}.call(this); | ||
this._queues.on("leftzero", () => { | ||
var base; | ||
return typeof (base = this._store.heartbeat).ref === "function" ? base.ref() : void 0; | ||
}); | ||
this._queues.on("zero", () => { | ||
var base; | ||
return typeof (base = this._store.heartbeat).unref === "function" ? base.unref() : void 0; | ||
}); | ||
} | ||
this._queues.on("zero", () => { | ||
var base; | ||
return typeof (base = this._store.heartbeat).unref === "function" ? base.unref() : void 0; | ||
}); | ||
} | ||
_validateOptions(options, invalid) { | ||
if (!(options != null && typeof options === "object" && invalid.length === 0)) { | ||
throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); | ||
} | ||
_validateOptions(options, invalid) { | ||
if (!(options != null && typeof options === "object" && invalid.length === 0)) { | ||
throw new Bottleneck.prototype.BottleneckError("Bottleneck v2 takes a single object argument. Refer to https://github.com/SGrondin/bottleneck#upgrading-to-v2 if you're upgrading from Bottleneck v1."); | ||
} | ||
} | ||
ready() { | ||
return this._store.ready; | ||
} | ||
ready() { | ||
return this._store.ready; | ||
} | ||
clients() { | ||
return this._store.clients; | ||
} | ||
clients() { | ||
return this._store.clients; | ||
} | ||
channel() { | ||
return `b_${this.id}`; | ||
} | ||
channel() { | ||
return `b_${this.id}`; | ||
} | ||
publish(message) { | ||
return this._store.__publish__(message); | ||
} | ||
publish(message) { | ||
return this._store.__publish__(message); | ||
} | ||
disconnect(flush = true) { | ||
return this._store.__disconnect__(flush); | ||
} | ||
disconnect(flush = true) { | ||
return this._store.__disconnect__(flush); | ||
} | ||
chain(_limiter) { | ||
this._limiter = _limiter; | ||
return this; | ||
} | ||
chain(_limiter) { | ||
this._limiter = _limiter; | ||
return this; | ||
} | ||
queued(priority) { | ||
return this._queues.queued(priority); | ||
} | ||
queued(priority) { | ||
return this._queues.queued(priority); | ||
} | ||
empty() { | ||
return this.queued() === 0 && this._submitLock.isEmpty(); | ||
} | ||
empty() { | ||
return this.queued() === 0 && this._submitLock.isEmpty(); | ||
} | ||
running() { | ||
return this._store.__running__(); | ||
} | ||
running() { | ||
return this._store.__running__(); | ||
} | ||
done() { | ||
return this._store.__done__(); | ||
} | ||
done() { | ||
return this._store.__done__(); | ||
} | ||
jobStatus(id) { | ||
return this._states.jobStatus(id); | ||
} | ||
jobStatus(id) { | ||
return this._states.jobStatus(id); | ||
} | ||
jobs(status) { | ||
return this._states.statusJobs(status); | ||
} | ||
jobs(status) { | ||
return this._states.statusJobs(status); | ||
} | ||
counts() { | ||
return this._states.statusCounts(); | ||
} | ||
counts() { | ||
return this._states.statusCounts(); | ||
} | ||
_sanitizePriority(priority) { | ||
var sProperty; | ||
sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; | ||
if (sProperty < 0) { | ||
return 0; | ||
} else if (sProperty > NUM_PRIORITIES - 1) { | ||
return NUM_PRIORITIES - 1; | ||
} else { | ||
return sProperty; | ||
} | ||
} | ||
_sanitizePriority(priority) { | ||
var sProperty; | ||
sProperty = ~~priority !== priority ? DEFAULT_PRIORITY : priority; | ||
_randomIndex() { | ||
return Math.random().toString(36).slice(2); | ||
if (sProperty < 0) { | ||
return 0; | ||
} else if (sProperty > NUM_PRIORITIES - 1) { | ||
return NUM_PRIORITIES - 1; | ||
} else { | ||
return sProperty; | ||
} | ||
} | ||
check(weight = 1) { | ||
return this._store.__check__(weight); | ||
} | ||
_randomIndex() { | ||
return Math.random().toString(36).slice(2); | ||
} | ||
_run(next, wait, index) { | ||
var _this = this; | ||
check(weight = 1) { | ||
return this._store.__check__(weight); | ||
} | ||
var completed, done; | ||
this.Events.trigger("debug", [`Scheduling ${next.options.id}`, { | ||
args: next.args, | ||
options: next.options | ||
}]); | ||
done = false; | ||
completed = (() => { | ||
var _ref = _asyncToGenerator(function* (...args) { | ||
var e, ref, running; | ||
if (!done) { | ||
try { | ||
done = true; | ||
_this._states.next(next.options.id); // DONE | ||
clearTimeout(_this._scheduled[index].expiration); | ||
delete _this._scheduled[index]; | ||
_this.Events.trigger("debug", [`Completed ${next.options.id}`, { | ||
args: next.args, | ||
options: next.options | ||
}]); | ||
_this.Events.trigger("done", [`Completed ${next.options.id}`, { | ||
args: next.args, | ||
options: next.options | ||
}]); | ||
_run(next, wait, index) { | ||
var _this = this; | ||
var _ref2 = yield _this._store.__free__(index, next.options.weight); | ||
var completed, done; | ||
this.Events.trigger("debug", [`Scheduling ${next.options.id}`, { | ||
args: next.args, | ||
options: next.options | ||
}]); | ||
done = false; | ||
running = _ref2.running; | ||
completed = | ||
/*#__PURE__*/ | ||
function () { | ||
var _ref = _asyncToGenerator(function* (...args) { | ||
var e, ref, running; | ||
_this.Events.trigger("debug", [`Freed ${next.options.id}`, { | ||
args: next.args, | ||
options: next.options | ||
}]); | ||
if (running === 0 && _this.empty()) { | ||
_this.Events.trigger("idle", []); | ||
} | ||
return (ref = next.cb) != null ? ref.apply({}, args) : void 0; | ||
} catch (error) { | ||
e = error; | ||
return _this.Events.trigger("error", [e]); | ||
} | ||
} | ||
}); | ||
if (!done) { | ||
try { | ||
done = true; | ||
return function completed() { | ||
return _ref.apply(this, arguments); | ||
}; | ||
})(); | ||
this._states.next(next.options.id); // RUNNING | ||
return this._scheduled[index] = { | ||
timeout: setTimeout(() => { | ||
this.Events.trigger("debug", [`Executing ${next.options.id}`, { | ||
args: next.args, | ||
options: next.options | ||
}]); | ||
this._states.next(next.options.id); // EXECUTING | ||
if (this._limiter != null) { | ||
return this._limiter.submit.apply(this._limiter, Array.prototype.concat(next.options, next.task, next.args, completed)); | ||
} else { | ||
return next.task.apply({}, next.args.concat(completed)); | ||
} | ||
}, wait), | ||
expiration: next.options.expiration != null ? setTimeout(() => { | ||
return completed(new Bottleneck.prototype.BottleneckError(`This job timed out after ${next.options.expiration} ms.`)); | ||
}, wait + next.options.expiration) : void 0, | ||
job: next | ||
}; | ||
} | ||
_this._states.next(next.options.id); // DONE | ||
_drainOne(capacity) { | ||
return this._registerLock.schedule(() => { | ||
var args, index, next, options, queue; | ||
if (this.queued() === 0) { | ||
return this.Promise.resolve(false); | ||
} | ||
queue = this._queues.getFirst(); | ||
var _next = next = queue.first(); | ||
clearTimeout(_this._scheduled[index].expiration); | ||
delete _this._scheduled[index]; | ||
options = _next.options; | ||
args = _next.args; | ||
_this.Events.trigger("debug", [`Completed ${next.options.id}`, { | ||
args: next.args, | ||
options: next.options | ||
}]); | ||
if (capacity != null && options.weight > capacity) { | ||
return this.Promise.resolve(false); | ||
} | ||
this.Events.trigger("debug", [`Draining ${options.id}`, { args, options }]); | ||
index = this._randomIndex(); | ||
return this._store.__register__(index, options.weight, options.expiration).then(({ success, wait, reservoir }) => { | ||
var empty; | ||
this.Events.trigger("debug", [`Drained ${options.id}`, { success, args, options }]); | ||
if (success) { | ||
queue.shift(); | ||
empty = this.empty(); | ||
if (empty) { | ||
this.Events.trigger("empty", []); | ||
_this.Events.trigger("done", [`Completed ${next.options.id}`, { | ||
args: next.args, | ||
options: next.options | ||
}]); | ||
var _ref2 = yield _this._store.__free__(index, next.options.weight); | ||
running = _ref2.running; | ||
_this.Events.trigger("debug", [`Freed ${next.options.id}`, { | ||
args: next.args, | ||
options: next.options | ||
}]); | ||
if (running === 0 && _this.empty()) { | ||
_this.Events.trigger("idle", []); | ||
} | ||
if (reservoir === 0) { | ||
this.Events.trigger("depleted", [empty]); | ||
} | ||
this._run(next, wait, index); | ||
return (ref = next.cb) != null ? ref.apply({}, args) : void 0; | ||
} catch (error) { | ||
e = error; | ||
return _this.Events.trigger("error", [e]); | ||
} | ||
return this.Promise.resolve(success); | ||
}); | ||
} | ||
}); | ||
} | ||
_drainAll(capacity) { | ||
return this._drainOne(capacity).then(success => { | ||
if (success) { | ||
return this._drainAll(); | ||
return function completed() { | ||
return _ref.apply(this, arguments); | ||
}; | ||
}(); | ||
this._states.next(next.options.id); // RUNNING | ||
return this._scheduled[index] = { | ||
timeout: setTimeout(() => { | ||
this.Events.trigger("debug", [`Executing ${next.options.id}`, { | ||
args: next.args, | ||
options: next.options | ||
}]); | ||
this._states.next(next.options.id); // EXECUTING | ||
if (this._limiter != null) { | ||
return this._limiter.submit.apply(this._limiter, Array.prototype.concat(next.options, next.task, next.args, completed)); | ||
} else { | ||
return this.Promise.resolve(success); | ||
return next.task.apply({}, next.args.concat(completed)); | ||
} | ||
}).catch(e => { | ||
return this.Events.trigger("error", [e]); | ||
}); | ||
} | ||
}, wait), | ||
expiration: next.options.expiration != null ? setTimeout(() => { | ||
return completed(new Bottleneck.prototype.BottleneckError(`This job timed out after ${next.options.expiration} ms.`)); | ||
}, wait + next.options.expiration) : void 0, | ||
job: next | ||
}; | ||
} | ||
_drop(job, message = "This job has been dropped by Bottleneck") { | ||
var ref; | ||
if (this._states.remove(job.options.id)) { | ||
if (this.rejectOnDrop) { | ||
if ((ref = job.cb) != null) { | ||
ref.apply({}, [new Bottleneck.prototype.BottleneckError(message)]); | ||
} | ||
} | ||
return this.Events.trigger("dropped", [job]); | ||
_drainOne(capacity) { | ||
return this._registerLock.schedule(() => { | ||
var args, index, next, options, queue; | ||
if (this.queued() === 0) { | ||
return this.Promise.resolve(false); | ||
} | ||
} | ||
_dropAllQueued(message) { | ||
return this._queues.shiftAll(job => { | ||
return this._drop(job, message); | ||
}); | ||
} | ||
queue = this._queues.getFirst(); | ||
stop(options = {}) { | ||
var done, waitForExecuting; | ||
options = parser.load(options, this.stopDefaults); | ||
waitForExecuting = at => { | ||
var finished; | ||
finished = () => { | ||
var counts; | ||
counts = this._states.counts; | ||
return counts[0] + counts[1] + counts[2] + counts[3] === at; | ||
}; | ||
return new this.Promise((resolve, reject) => { | ||
if (finished()) { | ||
return resolve(); | ||
} else { | ||
return this.on("done", () => { | ||
if (finished()) { | ||
this.removeAllListeners("done"); | ||
return resolve(); | ||
} | ||
}); | ||
} | ||
}); | ||
}; | ||
done = options.dropWaitingJobs ? (this._run = next => { | ||
return this._drop(next, options.dropErrorMessage); | ||
}, this._drainOne = () => { | ||
var _next2 = next = queue.first(); | ||
options = _next2.options; | ||
args = _next2.args; | ||
if (capacity != null && options.weight > capacity) { | ||
return this.Promise.resolve(false); | ||
}, this._registerLock.schedule(() => { | ||
return this._submitLock.schedule(() => { | ||
var k, ref, v; | ||
ref = this._scheduled; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (this.jobStatus(v.job.options.id) === "RUNNING") { | ||
clearTimeout(v.timeout); | ||
clearTimeout(v.expiration); | ||
this._drop(v.job, options.dropErrorMessage); | ||
} | ||
} | ||
this.Events.trigger("debug", [`Draining ${options.id}`, { | ||
args, | ||
options | ||
}]); | ||
index = this._randomIndex(); | ||
return this._store.__register__(index, options.weight, options.expiration).then(({ | ||
success, | ||
wait, | ||
reservoir | ||
}) => { | ||
var empty; | ||
this.Events.trigger("debug", [`Drained ${options.id}`, { | ||
success, | ||
args, | ||
options | ||
}]); | ||
if (success) { | ||
queue.shift(); | ||
empty = this.empty(); | ||
if (empty) { | ||
this.Events.trigger("empty", []); | ||
} | ||
this._dropAllQueued(options.dropErrorMessage); | ||
return waitForExecuting(0); | ||
}); | ||
})) : this.schedule({ | ||
priority: NUM_PRIORITIES - 1, | ||
weight: 0 | ||
}, () => { | ||
return waitForExecuting(1); | ||
}); | ||
this.submit = (...args) => { | ||
var _ref3, _ref4, _splice$call, _splice$call2; | ||
var cb, ref; | ||
ref = args, (_ref3 = ref, _ref4 = _toArray(_ref3), args = _ref4.slice(0), _ref3), (_splice$call = splice.call(args, -1), _splice$call2 = _slicedToArray(_splice$call, 1), cb = _splice$call2[0], _splice$call); | ||
return cb != null ? cb.apply({}, [new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)]) : void 0; | ||
}; | ||
this.stop = () => { | ||
return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); | ||
}; | ||
return done; | ||
} | ||
if (reservoir === 0) { | ||
this.Events.trigger("depleted", [empty]); | ||
} | ||
submit(...args) { | ||
var _this2 = this; | ||
this._run(next, wait, index); | ||
} | ||
var cb, job, options, ref, ref1, ref2, task; | ||
if (typeof args[0] === "function") { | ||
var _ref5, _ref6, _splice$call3, _splice$call4; | ||
return this.Promise.resolve(success); | ||
}); | ||
}); | ||
} | ||
ref = args, (_ref5 = ref, _ref6 = _toArray(_ref5), task = _ref6[0], args = _ref6.slice(1), _ref5), (_splice$call3 = splice.call(args, -1), _splice$call4 = _slicedToArray(_splice$call3, 1), cb = _splice$call4[0], _splice$call3); | ||
options = parser.load({}, this.jobDefaults, {}); | ||
_drainAll(capacity) { | ||
return this._drainOne(capacity).then(success => { | ||
if (success) { | ||
return this._drainAll(); | ||
} else { | ||
var _ref7, _ref8, _splice$call5, _splice$call6; | ||
return this.Promise.resolve(success); | ||
} | ||
}).catch(e => { | ||
return this.Events.trigger("error", [e]); | ||
}); | ||
} | ||
ref1 = args, (_ref7 = ref1, _ref8 = _toArray(_ref7), options = _ref8[0], task = _ref8[1], args = _ref8.slice(2), _ref7), (_splice$call5 = splice.call(args, -1), _splice$call6 = _slicedToArray(_splice$call5, 1), cb = _splice$call6[0], _splice$call5); | ||
options = parser.load(options, this.jobDefaults); | ||
} | ||
job = { options, task, args, cb }; | ||
options.priority = this._sanitizePriority(options.priority); | ||
if (options.id === this.jobDefaults.id) { | ||
options.id = `${options.id}-${this._randomIndex()}`; | ||
} | ||
if (this.jobStatus(options.id) != null) { | ||
if ((ref2 = job.cb) != null) { | ||
ref2.apply({}, [new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${options.id})`)]); | ||
_drop(job, message = "This job has been dropped by Bottleneck") { | ||
var ref; | ||
if (this._states.remove(job.options.id)) { | ||
if (this.rejectOnDrop) { | ||
if ((ref = job.cb) != null) { | ||
ref.apply({}, [new Bottleneck.prototype.BottleneckError(message)]); | ||
} | ||
return false; | ||
} | ||
this._states.start(options.id); // RECEIVED | ||
this.Events.trigger("debug", [`Queueing ${options.id}`, { args, options }]); | ||
return this._submitLock.schedule(_asyncToGenerator(function* () { | ||
var blocked, e, reachedHWM, ref3, shifted, strategy; | ||
try { | ||
var _ref10 = yield _this2._store.__submit__(_this2.queued(), options.weight); | ||
reachedHWM = _ref10.reachedHWM; | ||
blocked = _ref10.blocked; | ||
strategy = _ref10.strategy; | ||
return this.Events.trigger("dropped", [job]); | ||
} | ||
} | ||
_this2.Events.trigger("debug", [`Queued ${options.id}`, { args, options, reachedHWM, blocked }]); | ||
} catch (error) { | ||
e = error; | ||
_this2._states.remove(options.id); | ||
_this2.Events.trigger("debug", [`Could not queue ${options.id}`, { | ||
args, | ||
options, | ||
error: e | ||
}]); | ||
if ((ref3 = job.cb) != null) { | ||
ref3.apply({}, [e]); | ||
} | ||
return false; | ||
_dropAllQueued(message) { | ||
return this._queues.shiftAll(job => { | ||
return this._drop(job, message); | ||
}); | ||
} | ||
stop(options = {}) { | ||
var done, waitForExecuting; | ||
options = parser.load(options, this.stopDefaults); | ||
waitForExecuting = at => { | ||
var finished; | ||
finished = () => { | ||
var counts; | ||
counts = this._states.counts; | ||
return counts[0] + counts[1] + counts[2] + counts[3] === at; | ||
}; | ||
return new this.Promise((resolve, reject) => { | ||
if (finished()) { | ||
return resolve(); | ||
} else { | ||
return this.on("done", () => { | ||
if (finished()) { | ||
this.removeAllListeners("done"); | ||
return resolve(); | ||
} | ||
}); | ||
} | ||
if (blocked) { | ||
_this2._drop(job); | ||
return true; | ||
} else if (reachedHWM) { | ||
shifted = strategy === Bottleneck.prototype.strategy.LEAK ? _this2._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? _this2._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; | ||
if (shifted != null) { | ||
_this2._drop(shifted); | ||
}); | ||
}; | ||
done = options.dropWaitingJobs ? (this._run = next => { | ||
return this._drop(next, options.dropErrorMessage); | ||
}, this._drainOne = () => { | ||
return this.Promise.resolve(false); | ||
}, this._registerLock.schedule(() => { | ||
return this._submitLock.schedule(() => { | ||
var k, ref, v; | ||
ref = this._scheduled; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (this.jobStatus(v.job.options.id) === "RUNNING") { | ||
clearTimeout(v.timeout); | ||
clearTimeout(v.expiration); | ||
this._drop(v.job, options.dropErrorMessage); | ||
} | ||
if (shifted == null || strategy === Bottleneck.prototype.strategy.OVERFLOW) { | ||
if (shifted == null) { | ||
_this2._drop(job); | ||
} | ||
return reachedHWM; | ||
} | ||
} | ||
_this2._states.next(job.options.id); // QUEUED | ||
_this2._queues.push(options.priority, job); | ||
yield _this2._drainAll(); | ||
return reachedHWM; | ||
})); | ||
} | ||
schedule(...args) { | ||
var options, task, wrapped; | ||
if (typeof args[0] === "function") { | ||
var _args = args; | ||
this._dropAllQueued(options.dropErrorMessage); | ||
var _args2 = _toArray(_args); | ||
return waitForExecuting(0); | ||
}); | ||
})) : this.schedule({ | ||
priority: NUM_PRIORITIES - 1, | ||
weight: 0 | ||
}, () => { | ||
return waitForExecuting(1); | ||
}); | ||
task = _args2[0]; | ||
args = _args2.slice(1); | ||
this.submit = (...args) => { | ||
var _ref3, _ref4, _splice$call, _splice$call2; | ||
options = parser.load({}, this.jobDefaults, {}); | ||
} else { | ||
var _args3 = args; | ||
var cb, ref; | ||
ref = args, (_ref3 = ref, _ref4 = _toArray(_ref3), args = _ref4.slice(0), _ref3), (_splice$call = splice.call(args, -1), _splice$call2 = _slicedToArray(_splice$call, 1), cb = _splice$call2[0], _splice$call); | ||
return cb != null ? cb.apply({}, [new Bottleneck.prototype.BottleneckError(options.enqueueErrorMessage)]) : void 0; | ||
}; | ||
var _args4 = _toArray(_args3); | ||
this.stop = () => { | ||
return this.Promise.reject(new Bottleneck.prototype.BottleneckError("stop() has already been called")); | ||
}; | ||
options = _args4[0]; | ||
task = _args4[1]; | ||
args = _args4.slice(2); | ||
return done; | ||
} | ||
options = parser.load(options, this.jobDefaults); | ||
} | ||
wrapped = (...args) => { | ||
var _ref11, _ref12, _splice$call7, _splice$call8; | ||
submit(...args) { | ||
var _this2 = this; | ||
var cb, ref, returned; | ||
ref = args, (_ref11 = ref, _ref12 = _toArray(_ref11), args = _ref12.slice(0), _ref11), (_splice$call7 = splice.call(args, -1), _splice$call8 = _slicedToArray(_splice$call7, 1), cb = _splice$call8[0], _splice$call7); | ||
returned = task.apply({}, args); | ||
return (!((returned != null ? returned.then : void 0) != null && typeof returned.then === "function") ? this.Promise.resolve(returned) : returned).then(function (...args) { | ||
return cb.apply({}, Array.prototype.concat(null, args)); | ||
}).catch(function (...args) { | ||
return cb.apply({}, args); | ||
}); | ||
}; | ||
return new this.Promise((resolve, reject) => { | ||
return this.submit.apply({}, Array.prototype.concat(options, wrapped, args, function (...args) { | ||
return (args[0] != null ? reject : (args.shift(), resolve)).apply({}, args); | ||
})).catch(e => { | ||
return this.Events.trigger("error", [e]); | ||
}); | ||
}); | ||
} | ||
var cb, job, options, ref, ref1, ref2, task; | ||
wrap(fn) { | ||
var wrapped; | ||
wrapped = (...args) => { | ||
return this.schedule.apply({}, Array.prototype.concat(fn, args)); | ||
}; | ||
wrapped.withOptions = (options, ...args) => { | ||
return this.schedule.apply({}, Array.prototype.concat(options, fn, args)); | ||
}; | ||
return wrapped; | ||
} | ||
if (typeof args[0] === "function") { | ||
var _ref5, _ref6, _splice$call3, _splice$call4; | ||
updateSettings(options = {}) { | ||
var _this3 = this; | ||
ref = args, (_ref5 = ref, _ref6 = _toArray(_ref5), task = _ref6[0], args = _ref6.slice(1), _ref5), (_splice$call3 = splice.call(args, -1), _splice$call4 = _slicedToArray(_splice$call3, 1), cb = _splice$call4[0], _splice$call3); | ||
options = parser.load({}, this.jobDefaults, {}); | ||
} else { | ||
var _ref7, _ref8, _splice$call5, _splice$call6; | ||
return _asyncToGenerator(function* () { | ||
yield _this3._store.__updateSettings__(parser.overwrite(options, _this3.storeDefaults)); | ||
parser.overwrite(options, _this3.instanceDefaults, _this3); | ||
return _this3; | ||
})(); | ||
ref1 = args, (_ref7 = ref1, _ref8 = _toArray(_ref7), options = _ref8[0], task = _ref8[1], args = _ref8.slice(2), _ref7), (_splice$call5 = splice.call(args, -1), _splice$call6 = _slicedToArray(_splice$call5, 1), cb = _splice$call6[0], _splice$call5); | ||
options = parser.load(options, this.jobDefaults); | ||
} | ||
currentReservoir() { | ||
return this._store.__currentReservoir__(); | ||
job = { | ||
options, | ||
task, | ||
args, | ||
cb | ||
}; | ||
options.priority = this._sanitizePriority(options.priority); | ||
if (options.id === this.jobDefaults.id) { | ||
options.id = `${options.id}-${this._randomIndex()}`; | ||
} | ||
incrementReservoir(incr = 0) { | ||
return this._store.__incrementReservoir__(incr); | ||
if (this.jobStatus(options.id) != null) { | ||
if ((ref2 = job.cb) != null) { | ||
ref2.apply({}, [new Bottleneck.prototype.BottleneckError(`A job with the same id already exists (id=${options.id})`)]); | ||
} | ||
return false; | ||
} | ||
}; | ||
this._states.start(options.id); // RECEIVED | ||
Bottleneck.default = Bottleneck; | ||
Bottleneck.version = Bottleneck.prototype.version = packagejson.version; | ||
this.Events.trigger("debug", [`Queueing ${options.id}`, { | ||
args, | ||
options | ||
}]); | ||
return this._submitLock.schedule( | ||
/*#__PURE__*/ | ||
_asyncToGenerator(function* () { | ||
var blocked, e, reachedHWM, ref3, shifted, strategy; | ||
Bottleneck.strategy = Bottleneck.prototype.strategy = { | ||
LEAK: 1, | ||
OVERFLOW: 2, | ||
OVERFLOW_PRIORITY: 4, | ||
BLOCK: 3 | ||
}; | ||
try { | ||
var _ref10 = yield _this2._store.__submit__(_this2.queued(), options.weight); | ||
Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = require("./BottleneckError"); | ||
reachedHWM = _ref10.reachedHWM; | ||
blocked = _ref10.blocked; | ||
strategy = _ref10.strategy; | ||
Bottleneck.Group = Bottleneck.prototype.Group = require("./Group"); | ||
_this2.Events.trigger("debug", [`Queued ${options.id}`, { | ||
args, | ||
options, | ||
reachedHWM, | ||
blocked | ||
}]); | ||
} catch (error) { | ||
e = error; | ||
Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require("./RedisConnection"); | ||
_this2._states.remove(options.id); | ||
Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require("./IORedisConnection"); | ||
_this2.Events.trigger("debug", [`Could not queue ${options.id}`, { | ||
args, | ||
options, | ||
error: e | ||
}]); | ||
Bottleneck.Batcher = Bottleneck.prototype.Batcher = require("./Batcher"); | ||
if ((ref3 = job.cb) != null) { | ||
ref3.apply({}, [e]); | ||
} | ||
Bottleneck.prototype.jobDefaults = { | ||
priority: DEFAULT_PRIORITY, | ||
weight: 1, | ||
expiration: null, | ||
id: "<no-id>" | ||
}; | ||
return false; | ||
} | ||
Bottleneck.prototype.storeDefaults = { | ||
maxConcurrent: null, | ||
minTime: 0, | ||
highWater: null, | ||
strategy: Bottleneck.prototype.strategy.LEAK, | ||
penalty: null, | ||
reservoir: null, | ||
reservoirRefreshInterval: null, | ||
reservoirRefreshAmount: null | ||
}; | ||
if (blocked) { | ||
_this2._drop(job); | ||
Bottleneck.prototype.localStoreDefaults = { | ||
Promise: Promise, | ||
timeout: null, | ||
heartbeatInterval: 250 | ||
}; | ||
return true; | ||
} else if (reachedHWM) { | ||
shifted = strategy === Bottleneck.prototype.strategy.LEAK ? _this2._queues.shiftLastFrom(options.priority) : strategy === Bottleneck.prototype.strategy.OVERFLOW_PRIORITY ? _this2._queues.shiftLastFrom(options.priority + 1) : strategy === Bottleneck.prototype.strategy.OVERFLOW ? job : void 0; | ||
Bottleneck.prototype.redisStoreDefaults = { | ||
Promise: Promise, | ||
timeout: null, | ||
heartbeatInterval: 5000, | ||
clientOptions: {}, | ||
clusterNodes: null, | ||
clearDatastore: false, | ||
connection: null | ||
}; | ||
if (shifted != null) { | ||
_this2._drop(shifted); | ||
} | ||
Bottleneck.prototype.instanceDefaults = { | ||
datastore: "local", | ||
connection: null, | ||
id: "<no-id>", | ||
rejectOnDrop: true, | ||
trackDoneStatus: false, | ||
Promise: Promise | ||
}; | ||
if (shifted == null || strategy === Bottleneck.prototype.strategy.OVERFLOW) { | ||
if (shifted == null) { | ||
_this2._drop(job); | ||
} | ||
Bottleneck.prototype.stopDefaults = { | ||
enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", | ||
dropWaitingJobs: true, | ||
dropErrorMessage: "This limiter has been stopped." | ||
}; | ||
return reachedHWM; | ||
} | ||
} | ||
return Bottleneck; | ||
}.call(this); | ||
_this2._states.next(job.options.id); // QUEUED | ||
module.exports = Bottleneck; | ||
}).call(undefined); | ||
_this2._queues.push(options.priority, job); | ||
yield _this2._drainAll(); | ||
return reachedHWM; | ||
})); | ||
} | ||
schedule(...args) { | ||
var options, task, wrapped; | ||
if (typeof args[0] === "function") { | ||
var _args = args; | ||
var _args2 = _toArray(_args); | ||
task = _args2[0]; | ||
args = _args2.slice(1); | ||
options = parser.load({}, this.jobDefaults, {}); | ||
} else { | ||
var _args3 = args; | ||
var _args4 = _toArray(_args3); | ||
options = _args4[0]; | ||
task = _args4[1]; | ||
args = _args4.slice(2); | ||
options = parser.load(options, this.jobDefaults); | ||
} | ||
wrapped = (...args) => { | ||
var _ref11, _ref12, _splice$call7, _splice$call8; | ||
var cb, ref, returned; | ||
ref = args, (_ref11 = ref, _ref12 = _toArray(_ref11), args = _ref12.slice(0), _ref11), (_splice$call7 = splice.call(args, -1), _splice$call8 = _slicedToArray(_splice$call7, 1), cb = _splice$call8[0], _splice$call7); | ||
returned = task.apply({}, args); | ||
return (!((returned != null ? returned.then : void 0) != null && typeof returned.then === "function") ? this.Promise.resolve(returned) : returned).then(function (...args) { | ||
return cb.apply({}, Array.prototype.concat(null, args)); | ||
}).catch(function (...args) { | ||
return cb.apply({}, args); | ||
}); | ||
}; | ||
return new this.Promise((resolve, reject) => { | ||
return this.submit.apply({}, Array.prototype.concat(options, wrapped, args, function (...args) { | ||
return (args[0] != null ? reject : (args.shift(), resolve)).apply({}, args); | ||
})).catch(e => { | ||
return this.Events.trigger("error", [e]); | ||
}); | ||
}); | ||
} | ||
wrap(fn) { | ||
var wrapped; | ||
wrapped = (...args) => { | ||
return this.schedule.apply({}, Array.prototype.concat(fn, args)); | ||
}; | ||
wrapped.withOptions = (options, ...args) => { | ||
return this.schedule.apply({}, Array.prototype.concat(options, fn, args)); | ||
}; | ||
return wrapped; | ||
} | ||
updateSettings(options = {}) { | ||
var _this3 = this; | ||
return _asyncToGenerator(function* () { | ||
yield _this3._store.__updateSettings__(parser.overwrite(options, _this3.storeDefaults)); | ||
parser.overwrite(options, _this3.instanceDefaults, _this3); | ||
return _this3; | ||
})(); | ||
} | ||
currentReservoir() { | ||
return this._store.__currentReservoir__(); | ||
} | ||
incrementReservoir(incr = 0) { | ||
return this._store.__incrementReservoir__(incr); | ||
} | ||
} | ||
; | ||
Bottleneck.default = Bottleneck; | ||
Bottleneck.version = Bottleneck.prototype.version = packagejson.version; | ||
Bottleneck.strategy = Bottleneck.prototype.strategy = { | ||
LEAK: 1, | ||
OVERFLOW: 2, | ||
OVERFLOW_PRIORITY: 4, | ||
BLOCK: 3 | ||
}; | ||
Bottleneck.BottleneckError = Bottleneck.prototype.BottleneckError = require("./BottleneckError"); | ||
Bottleneck.Group = Bottleneck.prototype.Group = require("./Group"); | ||
Bottleneck.RedisConnection = Bottleneck.prototype.RedisConnection = require("./RedisConnection"); | ||
Bottleneck.IORedisConnection = Bottleneck.prototype.IORedisConnection = require("./IORedisConnection"); | ||
Bottleneck.Batcher = Bottleneck.prototype.Batcher = require("./Batcher"); | ||
Bottleneck.prototype.jobDefaults = { | ||
priority: DEFAULT_PRIORITY, | ||
weight: 1, | ||
expiration: null, | ||
id: "<no-id>" | ||
}; | ||
Bottleneck.prototype.storeDefaults = { | ||
maxConcurrent: null, | ||
minTime: 0, | ||
highWater: null, | ||
strategy: Bottleneck.prototype.strategy.LEAK, | ||
penalty: null, | ||
reservoir: null, | ||
reservoirRefreshInterval: null, | ||
reservoirRefreshAmount: null | ||
}; | ||
Bottleneck.prototype.localStoreDefaults = { | ||
Promise: Promise, | ||
timeout: null, | ||
heartbeatInterval: 250 | ||
}; | ||
Bottleneck.prototype.redisStoreDefaults = { | ||
Promise: Promise, | ||
timeout: null, | ||
heartbeatInterval: 5000, | ||
clientOptions: {}, | ||
clusterNodes: null, | ||
clearDatastore: false, | ||
connection: null | ||
}; | ||
Bottleneck.prototype.instanceDefaults = { | ||
datastore: "local", | ||
connection: null, | ||
id: "<no-id>", | ||
rejectOnDrop: true, | ||
trackDoneStatus: false, | ||
Promise: Promise | ||
}; | ||
Bottleneck.prototype.stopDefaults = { | ||
enqueueErrorMessage: "This limiter has been stopped and cannot accept new jobs.", | ||
dropWaitingJobs: true, | ||
dropErrorMessage: "This limiter has been stopped." | ||
}; | ||
return Bottleneck; | ||
}.call(void 0); | ||
module.exports = Bottleneck; |
"use strict"; | ||
(function () { | ||
var BottleneckError; | ||
BottleneckError = class BottleneckError extends Error {}; | ||
module.exports = BottleneckError; | ||
}).call(undefined); | ||
var BottleneckError; | ||
BottleneckError = class BottleneckError extends Error {}; | ||
module.exports = BottleneckError; |
"use strict"; | ||
(function () { | ||
var DLList; | ||
var DLList; | ||
DLList = class DLList { | ||
constructor(_queues) { | ||
this._queues = _queues; | ||
this._first = null; | ||
this._last = null; | ||
this.length = 0; | ||
} | ||
DLList = class DLList { | ||
constructor(_queues) { | ||
this._queues = _queues; | ||
this._first = null; | ||
this._last = null; | ||
this.length = 0; | ||
push(value) { | ||
var node, ref1; | ||
this.length++; | ||
if ((ref1 = this._queues) != null) { | ||
ref1.incr(); | ||
} | ||
push(value) { | ||
var node, ref1; | ||
this.length++; | ||
if ((ref1 = this._queues) != null) { | ||
ref1.incr(); | ||
} | ||
node = { | ||
value, | ||
next: null | ||
}; | ||
if (this._last != null) { | ||
this._last.next = node; | ||
this._last = node; | ||
} else { | ||
this._first = this._last = node; | ||
} | ||
return void 0; | ||
node = { | ||
value, | ||
next: null | ||
}; | ||
if (this._last != null) { | ||
this._last.next = node; | ||
this._last = node; | ||
} else { | ||
this._first = this._last = node; | ||
} | ||
shift() { | ||
var ref1, ref2, value; | ||
if (this._first == null) { | ||
return void 0; | ||
} else { | ||
this.length--; | ||
if ((ref1 = this._queues) != null) { | ||
ref1.decr(); | ||
} | ||
return void 0; | ||
} | ||
shift() { | ||
var ref1, ref2, value; | ||
if (this._first == null) { | ||
return void 0; | ||
} else { | ||
this.length--; | ||
if ((ref1 = this._queues) != null) { | ||
ref1.decr(); | ||
} | ||
value = this._first.value; | ||
this._first = (ref2 = this._first.next) != null ? ref2 : this._last = null; | ||
return value; | ||
} | ||
first() { | ||
if (this._first != null) { | ||
return this._first.value; | ||
} | ||
value = this._first.value; | ||
this._first = (ref2 = this._first.next) != null ? ref2 : this._last = null; | ||
return value; | ||
} | ||
first() { | ||
if (this._first != null) { | ||
return this._first.value; | ||
} | ||
} | ||
getArray() { | ||
var node, ref, results; | ||
node = this._first; | ||
results = []; | ||
while (node != null) { | ||
results.push((ref = node, node = node.next, ref.value)); | ||
} | ||
return results; | ||
getArray() { | ||
var node, ref, results; | ||
node = this._first; | ||
results = []; | ||
while (node != null) { | ||
results.push((ref = node, node = node.next, ref.value)); | ||
} | ||
forEachShift(cb) { | ||
var node; | ||
node = this.shift(); | ||
while (node != null) { | ||
cb(node), node = this.shift(); | ||
} | ||
return void 0; | ||
return results; | ||
} | ||
forEachShift(cb) { | ||
var node; | ||
node = this.shift(); | ||
while (node != null) { | ||
cb(node), node = this.shift(); | ||
} | ||
}; | ||
return void 0; | ||
} | ||
module.exports = DLList; | ||
}).call(undefined); | ||
}; | ||
module.exports = DLList; |
"use strict"; | ||
(function () { | ||
var Events; | ||
var Events; | ||
Events = class Events { | ||
constructor(instance) { | ||
this.instance = instance; | ||
this._events = {}; | ||
Events = class Events { | ||
constructor(instance) { | ||
this.instance = instance; | ||
this._events = {}; | ||
this.instance.on = (name, cb) => { | ||
return this._addListener(name, "many", cb); | ||
}; | ||
this.instance.once = (name, cb) => { | ||
return this._addListener(name, "once", cb); | ||
}; | ||
this.instance.removeAllListeners = (name = null) => { | ||
if (name != null) { | ||
return delete this._events[name]; | ||
} else { | ||
return this._events = {}; | ||
} | ||
}; | ||
} | ||
this.instance.on = (name, cb) => { | ||
return this._addListener(name, "many", cb); | ||
}; | ||
_addListener(name, status, cb) { | ||
var base; | ||
if ((base = this._events)[name] == null) { | ||
base[name] = []; | ||
this.instance.once = (name, cb) => { | ||
return this._addListener(name, "once", cb); | ||
}; | ||
this.instance.removeAllListeners = (name = null) => { | ||
if (name != null) { | ||
return delete this._events[name]; | ||
} else { | ||
return this._events = {}; | ||
} | ||
this._events[name].push({ cb, status }); | ||
return this.instance; | ||
}; | ||
} | ||
_addListener(name, status, cb) { | ||
var base; | ||
if ((base = this._events)[name] == null) { | ||
base[name] = []; | ||
} | ||
trigger(name, args) { | ||
if (name !== "debug") { | ||
this.trigger("debug", [`Event triggered: ${name}`, args]); | ||
} | ||
if (this._events[name] == null) { | ||
this._events[name].push({ | ||
cb, | ||
status | ||
}); | ||
return this.instance; | ||
} | ||
trigger(name, args) { | ||
if (name !== "debug") { | ||
this.trigger("debug", [`Event triggered: ${name}`, args]); | ||
} | ||
if (this._events[name] == null) { | ||
return; | ||
} | ||
this._events[name] = this._events[name].filter(function (listener) { | ||
return listener.status !== "none"; | ||
}); | ||
return this._events[name].forEach(listener => { | ||
var e, ret; | ||
if (listener.status === "none") { | ||
return; | ||
} | ||
this._events[name] = this._events[name].filter(function (listener) { | ||
return listener.status !== "none"; | ||
}); | ||
return this._events[name].forEach(listener => { | ||
var e, ret; | ||
if (listener.status === "none") { | ||
return; | ||
} | ||
if (listener.status === "once") { | ||
listener.status = "none"; | ||
} | ||
try { | ||
ret = listener.cb.apply({}, args); | ||
if (typeof (ret != null ? ret.then : void 0) === "function") { | ||
return ret.then(function () {}).catch(e => { | ||
return this.trigger("error", [e]); | ||
}); | ||
} | ||
} catch (error) { | ||
e = error; | ||
if ("name" !== "error") { | ||
if (listener.status === "once") { | ||
listener.status = "none"; | ||
} | ||
try { | ||
ret = listener.cb.apply({}, args); | ||
if (typeof (ret != null ? ret.then : void 0) === "function") { | ||
return ret.then(function () {}).catch(e => { | ||
return this.trigger("error", [e]); | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
} catch (error) { | ||
e = error; | ||
}; | ||
if ("name" !== "error") { | ||
return this.trigger("error", [e]); | ||
} | ||
} | ||
}); | ||
} | ||
module.exports = Events; | ||
}).call(undefined); | ||
}; | ||
module.exports = Events; |
216
lib/Group.js
"use strict"; | ||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } | ||
(function () { | ||
var Events, Group, IORedisConnection, RedisConnection, parser; | ||
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } | ||
parser = require("./parser"); | ||
var Events, Group, IORedisConnection, RedisConnection, parser; | ||
parser = require("./parser"); | ||
Events = require("./Events"); | ||
RedisConnection = require("./RedisConnection"); | ||
IORedisConnection = require("./IORedisConnection"); | ||
Events = require("./Events"); | ||
Group = function () { | ||
class Group { | ||
constructor(limiterOptions = {}) { | ||
this.deleteKey = this.deleteKey.bind(this); | ||
this.updateSettings = this.updateSettings.bind(this); | ||
this.limiterOptions = limiterOptions; | ||
parser.load(this.limiterOptions, this.defaults, this); | ||
this.Events = new Events(this); | ||
this.instances = {}; | ||
this.Bottleneck = require("./Bottleneck"); | ||
RedisConnection = require("./RedisConnection"); | ||
this._startAutoCleanup(); | ||
IORedisConnection = require("./IORedisConnection"); | ||
this.sharedConnection = this.connection != null; | ||
Group = function () { | ||
class Group { | ||
constructor(limiterOptions = {}) { | ||
this.deleteKey = this.deleteKey.bind(this); | ||
this.updateSettings = this.updateSettings.bind(this); | ||
this.limiterOptions = limiterOptions; | ||
parser.load(this.limiterOptions, this.defaults, this); | ||
this.Events = new Events(this); | ||
this.instances = {}; | ||
this.Bottleneck = require("./Bottleneck"); | ||
this._startAutoCleanup(); | ||
this.sharedConnection = this.connection != null; | ||
if (this.connection == null) { | ||
if (this.limiterOptions.datastore === "redis") { | ||
this.connection = new RedisConnection(Object.assign({}, this.limiterOptions, { Events: this.Events })); | ||
} else if (this.limiterOptions.datastore === "ioredis") { | ||
this.connection = new IORedisConnection(Object.assign({}, this.limiterOptions, { Events: this.Events })); | ||
} | ||
if (this.connection == null) { | ||
if (this.limiterOptions.datastore === "redis") { | ||
this.connection = new RedisConnection(Object.assign({}, this.limiterOptions, { | ||
Events: this.Events | ||
})); | ||
} else if (this.limiterOptions.datastore === "ioredis") { | ||
this.connection = new IORedisConnection(Object.assign({}, this.limiterOptions, { | ||
Events: this.Events | ||
})); | ||
} | ||
} | ||
} | ||
key(key = "") { | ||
var ref; | ||
return (ref = this.instances[key]) != null ? ref : (() => { | ||
var limiter; | ||
limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { | ||
id: `${this.id}-${key}`, | ||
timeout: this.timeout, | ||
connection: this.connection | ||
})); | ||
this.Events.trigger("created", [limiter, key]); | ||
return limiter; | ||
})(); | ||
} | ||
key(key = "") { | ||
var ref; | ||
return (ref = this.instances[key]) != null ? ref : (() => { | ||
var limiter; | ||
limiter = this.instances[key] = new this.Bottleneck(Object.assign(this.limiterOptions, { | ||
id: `${this.id}-${key}`, | ||
timeout: this.timeout, | ||
connection: this.connection | ||
})); | ||
this.Events.trigger("created", [limiter, key]); | ||
return limiter; | ||
})(); | ||
} | ||
deleteKey(key = "") { | ||
var instance; | ||
instance = this.instances[key]; | ||
delete this.instances[key]; | ||
return instance != null ? instance.disconnect() : void 0; | ||
deleteKey(key = "") { | ||
var instance; | ||
instance = this.instances[key]; | ||
delete this.instances[key]; | ||
return instance != null ? instance.disconnect() : void 0; | ||
} | ||
limiters() { | ||
var k, ref, results, v; | ||
ref = this.instances; | ||
results = []; | ||
for (k in ref) { | ||
v = ref[k]; | ||
results.push({ | ||
key: k, | ||
limiter: v | ||
}); | ||
} | ||
limiters() { | ||
var k, ref, results, v; | ||
ref = this.instances; | ||
return results; | ||
} | ||
keys() { | ||
return Object.keys(this.instances); | ||
} | ||
_startAutoCleanup() { | ||
var _this = this; | ||
var base; | ||
clearInterval(this.interval); | ||
return typeof (base = this.interval = setInterval( | ||
/*#__PURE__*/ | ||
_asyncToGenerator(function* () { | ||
var e, k, ref, results, time, v; | ||
time = Date.now(); | ||
ref = _this.instances; | ||
results = []; | ||
for (k in ref) { | ||
v = ref[k]; | ||
results.push({ | ||
key: k, | ||
limiter: v | ||
}); | ||
try { | ||
if (yield v._store.__groupCheck__(time)) { | ||
results.push(_this.deleteKey(k)); | ||
} else { | ||
results.push(void 0); | ||
} | ||
} catch (error) { | ||
e = error; | ||
results.push(v.Events.trigger("error", [e])); | ||
} | ||
} | ||
return results; | ||
} | ||
}), this.timeout / 2)).unref === "function" ? base.unref() : void 0; | ||
} | ||
keys() { | ||
return Object.keys(this.instances); | ||
} | ||
updateSettings(options = {}) { | ||
parser.overwrite(options, this.defaults, this); | ||
parser.overwrite(options, options, this.limiterOptions); | ||
_startAutoCleanup() { | ||
var _this = this; | ||
var base; | ||
clearInterval(this.interval); | ||
return typeof (base = this.interval = setInterval(_asyncToGenerator(function* () { | ||
var e, k, ref, results, time, v; | ||
time = Date.now(); | ||
ref = _this.instances; | ||
results = []; | ||
for (k in ref) { | ||
v = ref[k]; | ||
try { | ||
if (yield v._store.__groupCheck__(time)) { | ||
results.push(_this.deleteKey(k)); | ||
} else { | ||
results.push(void 0); | ||
} | ||
} catch (error) { | ||
e = error; | ||
results.push(v.Events.trigger("error", [e])); | ||
} | ||
} | ||
return results; | ||
}), this.timeout / 2)).unref === "function" ? base.unref() : void 0; | ||
if (options.timeout != null) { | ||
return this._startAutoCleanup(); | ||
} | ||
} | ||
updateSettings(options = {}) { | ||
parser.overwrite(options, this.defaults, this); | ||
parser.overwrite(options, options, this.limiterOptions); | ||
if (options.timeout != null) { | ||
return this._startAutoCleanup(); | ||
} | ||
} | ||
disconnect(flush = true) { | ||
var ref; | ||
disconnect(flush = true) { | ||
var ref; | ||
if (!this.sharedConnection) { | ||
return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; | ||
} | ||
if (!this.sharedConnection) { | ||
return (ref = this.connection) != null ? ref.disconnect(flush) : void 0; | ||
} | ||
} | ||
}; | ||
} | ||
Group.prototype.defaults = { | ||
timeout: 1000 * 60 * 5, | ||
connection: null, | ||
id: "group-key" | ||
}; | ||
; | ||
Group.prototype.defaults = { | ||
timeout: 1000 * 60 * 5, | ||
connection: null, | ||
id: "group-key" | ||
}; | ||
return Group; | ||
}.call(void 0); | ||
return Group; | ||
}.call(this); | ||
module.exports = Group; | ||
}).call(undefined); | ||
module.exports = Group; |
"use strict"; | ||
(function () { | ||
module.exports = require("./Bottleneck"); | ||
}).call(undefined); | ||
module.exports = require("./Bottleneck"); |
"use strict"; | ||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } | ||
(function () { | ||
var Events, IORedisConnection, Scripts, parser; | ||
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } | ||
parser = require("./parser"); | ||
var Events, IORedisConnection, Scripts, parser; | ||
parser = require("./parser"); | ||
Events = require("./Events"); | ||
Scripts = require("./Scripts"); | ||
Events = require("./Events"); | ||
IORedisConnection = function () { | ||
class IORedisConnection { | ||
constructor(options = {}) { | ||
var Redis; | ||
Redis = eval("require")("ioredis"); // Obfuscated or else Webpack/Angular will try to inline the optional ioredis module | ||
Scripts = require("./Scripts"); | ||
parser.load(options, this.defaults, this); | ||
IORedisConnection = function () { | ||
class IORedisConnection { | ||
constructor(options = {}) { | ||
var Redis; | ||
Redis = eval("require")("ioredis"); // Obfuscated or else Webpack/Angular will try to inline the optional ioredis module | ||
parser.load(options, this.defaults, this); | ||
if (this.Events == null) { | ||
this.Events = new Events(this); | ||
if (this.Events == null) { | ||
this.Events = new Events(this); | ||
} | ||
this.terminated = false; | ||
if (this.clusterNodes != null) { | ||
this.client = new Redis.Cluster(this.clusterNodes, this.clientOptions); | ||
this.subscriber = new Redis.Cluster(this.clusterNodes, this.clientOptions); | ||
} else { | ||
if (this.client == null) { | ||
this.client = new Redis(this.clientOptions); | ||
} | ||
this.terminated = false; | ||
if (this.clusterNodes != null) { | ||
this.client = new Redis.Cluster(this.clusterNodes, this.clientOptions); | ||
this.subscriber = new Redis.Cluster(this.clusterNodes, this.clientOptions); | ||
} else { | ||
if (this.client == null) { | ||
this.client = new Redis(this.clientOptions); | ||
} | ||
this.subscriber = this.client.duplicate(); | ||
} | ||
this.limiters = {}; | ||
this.ready = this.Promise.all([this._setup(this.client, false), this._setup(this.subscriber, true)]).then(() => { | ||
this._loadScripts(); | ||
return { client: this.client, subscriber: this.subscriber }; | ||
}); | ||
this.subscriber = this.client.duplicate(); | ||
} | ||
_setup(client, subscriber) { | ||
return new this.Promise((resolve, reject) => { | ||
client.on("error", e => { | ||
return this.Events.trigger("error", [e]); | ||
}); | ||
if (subscriber) { | ||
client.on("message", (channel, message) => { | ||
var ref; | ||
return (ref = this.limiters[channel]) != null ? ref._store.onMessage(message) : void 0; | ||
}); | ||
} | ||
if (client.status === "ready") { | ||
return resolve(); | ||
} else { | ||
return client.once("ready", resolve); | ||
} | ||
this.limiters = {}; | ||
this.ready = this.Promise.all([this._setup(this.client, false), this._setup(this.subscriber, true)]).then(() => { | ||
this._loadScripts(); | ||
return { | ||
client: this.client, | ||
subscriber: this.subscriber | ||
}; | ||
}); | ||
} | ||
_setup(client, subscriber) { | ||
return new this.Promise((resolve, reject) => { | ||
client.on("error", e => { | ||
return this.Events.trigger("error", [e]); | ||
}); | ||
} | ||
_loadScripts() { | ||
return Scripts.names.forEach(name => { | ||
return this.client.defineCommand(name, { | ||
lua: Scripts.payload(name) | ||
if (subscriber) { | ||
client.on("message", (channel, message) => { | ||
var ref; | ||
return (ref = this.limiters[channel]) != null ? ref._store.onMessage(message) : void 0; | ||
}); | ||
} | ||
if (client.status === "ready") { | ||
return resolve(); | ||
} else { | ||
return client.once("ready", resolve); | ||
} | ||
}); | ||
} | ||
_loadScripts() { | ||
return Scripts.names.forEach(name => { | ||
return this.client.defineCommand(name, { | ||
lua: Scripts.payload(name) | ||
}); | ||
} | ||
}); | ||
} | ||
__addLimiter__(instance) { | ||
__addLimiter__(instance) { | ||
var channel; | ||
channel = instance.channel(); | ||
return new this.Promise((resolve, reject) => { | ||
return this.subscriber.subscribe(channel, () => { | ||
this.limiters[channel] = instance; | ||
return resolve(); | ||
}); | ||
}); | ||
} | ||
__removeLimiter__(instance) { | ||
var _this = this; | ||
return _asyncToGenerator(function* () { | ||
var channel; | ||
channel = instance.channel(); | ||
return new this.Promise((resolve, reject) => { | ||
return this.subscriber.subscribe(channel, () => { | ||
this.limiters[channel] = instance; | ||
return resolve(); | ||
}); | ||
}); | ||
} | ||
__removeLimiter__(instance) { | ||
var _this = this; | ||
if (!_this.terminated) { | ||
yield _this.subscriber.unsubscribe(channel); | ||
} | ||
return _asyncToGenerator(function* () { | ||
var channel; | ||
channel = instance.channel(); | ||
if (!_this.terminated) { | ||
yield _this.subscriber.unsubscribe(channel); | ||
} | ||
return delete _this.limiters[channel]; | ||
})(); | ||
} | ||
return delete _this.limiters[channel]; | ||
})(); | ||
} | ||
__scriptArgs__(name, id, args, cb) { | ||
var keys; | ||
keys = Scripts.keys(name, id); | ||
return [keys.length].concat(keys, args, cb); | ||
} | ||
__scriptArgs__(name, id, args, cb) { | ||
var keys; | ||
keys = Scripts.keys(name, id); | ||
return [keys.length].concat(keys, args, cb); | ||
} | ||
__scriptFn__(name) { | ||
return this.client[name].bind(this.client); | ||
} | ||
__scriptFn__(name) { | ||
return this.client[name].bind(this.client); | ||
} | ||
disconnect(flush = true) { | ||
var i, k, len, ref; | ||
ref = Object.keys(this.limiters); | ||
for (i = 0, len = ref.length; i < len; i++) { | ||
k = ref[i]; | ||
clearInterval(this.limiters[k]._store.heartbeat); | ||
} | ||
this.limiters = {}; | ||
this.terminated = true; | ||
if (flush) { | ||
return this.Promise.all([this.client.quit(), this.subscriber.quit()]); | ||
} else { | ||
this.client.disconnect(); | ||
this.subscriber.disconnect(); | ||
return this.Promise.resolve(); | ||
} | ||
disconnect(flush = true) { | ||
var i, k, len, ref; | ||
ref = Object.keys(this.limiters); | ||
for (i = 0, len = ref.length; i < len; i++) { | ||
k = ref[i]; | ||
clearInterval(this.limiters[k]._store.heartbeat); | ||
} | ||
}; | ||
this.limiters = {}; | ||
this.terminated = true; | ||
IORedisConnection.prototype.datastore = "ioredis"; | ||
if (flush) { | ||
return this.Promise.all([this.client.quit(), this.subscriber.quit()]); | ||
} else { | ||
this.client.disconnect(); | ||
this.subscriber.disconnect(); | ||
return this.Promise.resolve(); | ||
} | ||
} | ||
IORedisConnection.prototype.defaults = { | ||
clientOptions: {}, | ||
clusterNodes: null, | ||
client: null, | ||
Promise: Promise, | ||
Events: null | ||
}; | ||
} | ||
return IORedisConnection; | ||
}.call(this); | ||
; | ||
IORedisConnection.prototype.datastore = "ioredis"; | ||
IORedisConnection.prototype.defaults = { | ||
clientOptions: {}, | ||
clusterNodes: null, | ||
client: null, | ||
Promise: Promise, | ||
Events: null | ||
}; | ||
return IORedisConnection; | ||
}.call(void 0); | ||
module.exports = IORedisConnection; | ||
}).call(undefined); | ||
module.exports = IORedisConnection; |
"use strict"; | ||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } | ||
(function () { | ||
var BottleneckError, LocalDatastore, parser; | ||
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } | ||
parser = require("./parser"); | ||
var BottleneckError, LocalDatastore, parser; | ||
parser = require("./parser"); | ||
BottleneckError = require("./BottleneckError"); | ||
LocalDatastore = class LocalDatastore { | ||
constructor(instance, storeOptions, storeInstanceOptions) { | ||
var base; | ||
this.instance = instance; | ||
this.storeOptions = storeOptions; | ||
parser.load(storeInstanceOptions, storeInstanceOptions, this); | ||
this._nextRequest = this._lastReservoirRefresh = Date.now(); | ||
this._running = 0; | ||
this._done = 0; | ||
this._unblockTime = 0; | ||
this.ready = this.yieldLoop(); | ||
this.clients = {}; | ||
BottleneckError = require("./BottleneckError"); | ||
if (typeof (base = this.heartbeat = setInterval(() => { | ||
var now, reservoirRefreshActive; | ||
now = Date.now(); | ||
reservoirRefreshActive = this.storeOptions.reservoirRefreshInterval != null && this.storeOptions.reservoirRefreshAmount != null; | ||
LocalDatastore = class LocalDatastore { | ||
constructor(instance, storeOptions, storeInstanceOptions) { | ||
var base; | ||
this.instance = instance; | ||
this.storeOptions = storeOptions; | ||
parser.load(storeInstanceOptions, storeInstanceOptions, this); | ||
this._nextRequest = this._lastReservoirRefresh = Date.now(); | ||
this._running = 0; | ||
this._done = 0; | ||
this._unblockTime = 0; | ||
this.ready = this.yieldLoop(); | ||
this.clients = {}; | ||
if (typeof (base = this.heartbeat = setInterval(() => { | ||
var now, reservoirRefreshActive; | ||
now = Date.now(); | ||
reservoirRefreshActive = this.storeOptions.reservoirRefreshInterval != null && this.storeOptions.reservoirRefreshAmount != null; | ||
if (reservoirRefreshActive && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { | ||
this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; | ||
this._lastReservoirRefresh = now; | ||
return this.instance._drainAll(this.computeCapacity()); | ||
} | ||
}, this.heartbeatInterval)).unref === "function") { | ||
base.unref(); | ||
if (reservoirRefreshActive && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) { | ||
this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount; | ||
this._lastReservoirRefresh = now; | ||
return this.instance._drainAll(this.computeCapacity()); | ||
} | ||
}, this.heartbeatInterval)).unref === "function") { | ||
base.unref(); | ||
} | ||
} | ||
__publish__(message) { | ||
var _this = this; | ||
__publish__(message) { | ||
var _this = this; | ||
return _asyncToGenerator(function* () { | ||
yield _this.yieldLoop(); | ||
return _this.instance.Events.trigger("message", [message.toString()]); | ||
})(); | ||
} | ||
return _asyncToGenerator(function* () { | ||
yield _this.yieldLoop(); | ||
return _this.instance.Events.trigger("message", [message.toString()]); | ||
})(); | ||
} | ||
__disconnect__(flush) { | ||
clearInterval(this.heartbeat); | ||
return this.Promise.resolve(); | ||
} | ||
__disconnect__(flush) { | ||
clearInterval(this.heartbeat); | ||
return this.Promise.resolve(); | ||
} | ||
yieldLoop(t = 0) { | ||
return new this.Promise(function (resolve, reject) { | ||
return setTimeout(resolve, t); | ||
}); | ||
} | ||
yieldLoop(t = 0) { | ||
return new this.Promise(function (resolve, reject) { | ||
return setTimeout(resolve, t); | ||
}); | ||
} | ||
computePenalty() { | ||
var ref; | ||
return (ref = this.storeOptions.penalty) != null ? ref : 15 * this.storeOptions.minTime || 5000; | ||
} | ||
computePenalty() { | ||
var ref; | ||
return (ref = this.storeOptions.penalty) != null ? ref : 15 * this.storeOptions.minTime || 5000; | ||
} | ||
__updateSettings__(options) { | ||
var _this2 = this; | ||
__updateSettings__(options) { | ||
var _this2 = this; | ||
return _asyncToGenerator(function* () { | ||
yield _this2.yieldLoop(); | ||
parser.overwrite(options, options, _this2.storeOptions); | ||
_this2.instance._drainAll(_this2.computeCapacity()); | ||
return true; | ||
})(); | ||
} | ||
return _asyncToGenerator(function* () { | ||
yield _this2.yieldLoop(); | ||
parser.overwrite(options, options, _this2.storeOptions); | ||
__running__() { | ||
var _this3 = this; | ||
_this2.instance._drainAll(_this2.computeCapacity()); | ||
return _asyncToGenerator(function* () { | ||
yield _this3.yieldLoop(); | ||
return _this3._running; | ||
})(); | ||
} | ||
return true; | ||
})(); | ||
} | ||
__done__() { | ||
var _this4 = this; | ||
__running__() { | ||
var _this3 = this; | ||
return _asyncToGenerator(function* () { | ||
yield _this4.yieldLoop(); | ||
return _this4._done; | ||
})(); | ||
} | ||
return _asyncToGenerator(function* () { | ||
yield _this3.yieldLoop(); | ||
return _this3._running; | ||
})(); | ||
} | ||
__groupCheck__(time) { | ||
var _this5 = this; | ||
__done__() { | ||
var _this4 = this; | ||
return _asyncToGenerator(function* () { | ||
yield _this5.yieldLoop(); | ||
return _this5._nextRequest + _this5.timeout < time; | ||
})(); | ||
} | ||
return _asyncToGenerator(function* () { | ||
yield _this4.yieldLoop(); | ||
return _this4._done; | ||
})(); | ||
} | ||
computeCapacity() { | ||
var maxConcurrent, reservoir; | ||
var _storeOptions = this.storeOptions; | ||
maxConcurrent = _storeOptions.maxConcurrent; | ||
reservoir = _storeOptions.reservoir; | ||
__groupCheck__(time) { | ||
var _this5 = this; | ||
if (maxConcurrent != null && reservoir != null) { | ||
return Math.min(maxConcurrent - this._running, reservoir); | ||
} else if (maxConcurrent != null) { | ||
return maxConcurrent - this._running; | ||
} else if (reservoir != null) { | ||
return reservoir; | ||
} else { | ||
return null; | ||
} | ||
} | ||
return _asyncToGenerator(function* () { | ||
yield _this5.yieldLoop(); | ||
return _this5._nextRequest + _this5.timeout < time; | ||
})(); | ||
} | ||
conditionsCheck(weight) { | ||
var capacity; | ||
capacity = this.computeCapacity(); | ||
return capacity == null || weight <= capacity; | ||
computeCapacity() { | ||
var maxConcurrent, reservoir; | ||
var _this$storeOptions = this.storeOptions; | ||
maxConcurrent = _this$storeOptions.maxConcurrent; | ||
reservoir = _this$storeOptions.reservoir; | ||
if (maxConcurrent != null && reservoir != null) { | ||
return Math.min(maxConcurrent - this._running, reservoir); | ||
} else if (maxConcurrent != null) { | ||
return maxConcurrent - this._running; | ||
} else if (reservoir != null) { | ||
return reservoir; | ||
} else { | ||
return null; | ||
} | ||
} | ||
__incrementReservoir__(incr) { | ||
var _this6 = this; | ||
conditionsCheck(weight) { | ||
var capacity; | ||
capacity = this.computeCapacity(); | ||
return capacity == null || weight <= capacity; | ||
} | ||
return _asyncToGenerator(function* () { | ||
var reservoir; | ||
yield _this6.yieldLoop(); | ||
reservoir = _this6.storeOptions.reservoir += incr; | ||
_this6.instance._drainAll(_this6.computeCapacity()); | ||
return reservoir; | ||
})(); | ||
} | ||
__incrementReservoir__(incr) { | ||
var _this6 = this; | ||
__currentReservoir__() { | ||
var _this7 = this; | ||
return _asyncToGenerator(function* () { | ||
var reservoir; | ||
yield _this6.yieldLoop(); | ||
reservoir = _this6.storeOptions.reservoir += incr; | ||
return _asyncToGenerator(function* () { | ||
yield _this7.yieldLoop(); | ||
return _this7.storeOptions.reservoir; | ||
})(); | ||
} | ||
_this6.instance._drainAll(_this6.computeCapacity()); | ||
isBlocked(now) { | ||
return this._unblockTime >= now; | ||
} | ||
return reservoir; | ||
})(); | ||
} | ||
check(weight, now) { | ||
return this.conditionsCheck(weight) && this._nextRequest - now <= 0; | ||
} | ||
__currentReservoir__() { | ||
var _this7 = this; | ||
__check__(weight) { | ||
var _this8 = this; | ||
return _asyncToGenerator(function* () { | ||
yield _this7.yieldLoop(); | ||
return _this7.storeOptions.reservoir; | ||
})(); | ||
} | ||
return _asyncToGenerator(function* () { | ||
var now; | ||
yield _this8.yieldLoop(); | ||
now = Date.now(); | ||
return _this8.check(weight, now); | ||
})(); | ||
} | ||
isBlocked(now) { | ||
return this._unblockTime >= now; | ||
} | ||
__register__(index, weight, expiration) { | ||
var _this9 = this; | ||
check(weight, now) { | ||
return this.conditionsCheck(weight) && this._nextRequest - now <= 0; | ||
} | ||
return _asyncToGenerator(function* () { | ||
var now, wait; | ||
yield _this9.yieldLoop(); | ||
now = Date.now(); | ||
if (_this9.conditionsCheck(weight)) { | ||
_this9._running += weight; | ||
if (_this9.storeOptions.reservoir != null) { | ||
_this9.storeOptions.reservoir -= weight; | ||
} | ||
wait = Math.max(_this9._nextRequest - now, 0); | ||
_this9._nextRequest = now + wait + _this9.storeOptions.minTime; | ||
return { | ||
success: true, | ||
wait, | ||
reservoir: _this9.storeOptions.reservoir | ||
}; | ||
} else { | ||
return { | ||
success: false | ||
}; | ||
} | ||
})(); | ||
} | ||
__check__(weight) { | ||
var _this8 = this; | ||
strategyIsBlock() { | ||
return this.storeOptions.strategy === 3; | ||
} | ||
return _asyncToGenerator(function* () { | ||
var now; | ||
yield _this8.yieldLoop(); | ||
now = Date.now(); | ||
return _this8.check(weight, now); | ||
})(); | ||
} | ||
__submit__(queueLength, weight) { | ||
var _this10 = this; | ||
__register__(index, weight, expiration) { | ||
var _this9 = this; | ||
return _asyncToGenerator(function* () { | ||
var blocked, now, reachedHWM; | ||
yield _this10.yieldLoop(); | ||
if (_this10.storeOptions.maxConcurrent != null && weight > _this10.storeOptions.maxConcurrent) { | ||
throw new BottleneckError(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${_this10.storeOptions.maxConcurrent}`); | ||
return _asyncToGenerator(function* () { | ||
var now, wait; | ||
yield _this9.yieldLoop(); | ||
now = Date.now(); | ||
if (_this9.conditionsCheck(weight)) { | ||
_this9._running += weight; | ||
if (_this9.storeOptions.reservoir != null) { | ||
_this9.storeOptions.reservoir -= weight; | ||
} | ||
now = Date.now(); | ||
reachedHWM = _this10.storeOptions.highWater != null && queueLength === _this10.storeOptions.highWater && !_this10.check(weight, now); | ||
blocked = _this10.strategyIsBlock() && (reachedHWM || _this10.isBlocked(now)); | ||
if (blocked) { | ||
_this10._unblockTime = now + _this10.computePenalty(); | ||
_this10._nextRequest = _this10._unblockTime + _this10.storeOptions.minTime; | ||
_this10.instance._dropAllQueued(); | ||
} | ||
wait = Math.max(_this9._nextRequest - now, 0); | ||
_this9._nextRequest = now + wait + _this9.storeOptions.minTime; | ||
return { | ||
reachedHWM, | ||
blocked, | ||
strategy: _this10.storeOptions.strategy | ||
success: true, | ||
wait, | ||
reservoir: _this9.storeOptions.reservoir | ||
}; | ||
})(); | ||
} | ||
__free__(index, weight) { | ||
var _this11 = this; | ||
return _asyncToGenerator(function* () { | ||
yield _this11.yieldLoop(); | ||
_this11._running -= weight; | ||
_this11._done += weight; | ||
_this11.instance._drainAll(_this11.computeCapacity()); | ||
} else { | ||
return { | ||
running: _this11._running | ||
success: false | ||
}; | ||
})(); | ||
} | ||
} | ||
})(); | ||
} | ||
}; | ||
strategyIsBlock() { | ||
return this.storeOptions.strategy === 3; | ||
} | ||
module.exports = LocalDatastore; | ||
}).call(undefined); | ||
__submit__(queueLength, weight) { | ||
var _this10 = this; | ||
return _asyncToGenerator(function* () { | ||
var blocked, now, reachedHWM; | ||
yield _this10.yieldLoop(); | ||
if (_this10.storeOptions.maxConcurrent != null && weight > _this10.storeOptions.maxConcurrent) { | ||
throw new BottleneckError(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${_this10.storeOptions.maxConcurrent}`); | ||
} | ||
now = Date.now(); | ||
reachedHWM = _this10.storeOptions.highWater != null && queueLength === _this10.storeOptions.highWater && !_this10.check(weight, now); | ||
blocked = _this10.strategyIsBlock() && (reachedHWM || _this10.isBlocked(now)); | ||
if (blocked) { | ||
_this10._unblockTime = now + _this10.computePenalty(); | ||
_this10._nextRequest = _this10._unblockTime + _this10.storeOptions.minTime; | ||
_this10.instance._dropAllQueued(); | ||
} | ||
return { | ||
reachedHWM, | ||
blocked, | ||
strategy: _this10.storeOptions.strategy | ||
}; | ||
})(); | ||
} | ||
__free__(index, weight) { | ||
var _this11 = this; | ||
return _asyncToGenerator(function* () { | ||
yield _this11.yieldLoop(); | ||
_this11._running -= weight; | ||
_this11._done += weight; | ||
_this11.instance._drainAll(_this11.computeCapacity()); | ||
return { | ||
running: _this11._running | ||
}; | ||
})(); | ||
} | ||
}; | ||
module.exports = LocalDatastore; |
"use strict"; | ||
(function () { | ||
exports.load = function (received, defaults, onto = {}) { | ||
var k, ref, v; | ||
for (k in defaults) { | ||
v = defaults[k]; | ||
onto[k] = (ref = received[k]) != null ? ref : v; | ||
exports.load = function (received, defaults, onto = {}) { | ||
var k, ref, v; | ||
for (k in defaults) { | ||
v = defaults[k]; | ||
onto[k] = (ref = received[k]) != null ? ref : v; | ||
} | ||
return onto; | ||
}; | ||
exports.overwrite = function (received, defaults, onto = {}) { | ||
var k, v; | ||
for (k in received) { | ||
v = received[k]; | ||
if (defaults[k] !== void 0) { | ||
onto[k] = v; | ||
} | ||
return onto; | ||
}; | ||
} | ||
exports.overwrite = function (received, defaults, onto = {}) { | ||
var k, v; | ||
for (k in received) { | ||
v = received[k]; | ||
if (defaults[k] !== void 0) { | ||
onto[k] = v; | ||
} | ||
} | ||
return onto; | ||
}; | ||
}).call(undefined); | ||
return onto; | ||
}; |
"use strict"; | ||
(function () { | ||
var DLList, Events, Queues; | ||
var DLList, Events, Queues; | ||
DLList = require("./DLList"); | ||
Events = require("./Events"); | ||
Queues = class Queues { | ||
constructor(num_priorities) { | ||
var i; | ||
this.Events = new Events(this); | ||
this._length = 0; | ||
DLList = require("./DLList"); | ||
this._lists = function () { | ||
var j, ref, results; | ||
results = []; | ||
Events = require("./Events"); | ||
for (i = j = 1, ref = num_priorities; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) { | ||
results.push(new DLList(this)); | ||
} | ||
Queues = class Queues { | ||
constructor(num_priorities) { | ||
var i; | ||
this.Events = new Events(this); | ||
this._length = 0; | ||
this._lists = function () { | ||
var j, ref, results; | ||
results = []; | ||
for (i = j = 1, ref = num_priorities; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) { | ||
results.push(new DLList(this)); | ||
} | ||
return results; | ||
}.call(this); | ||
} | ||
return results; | ||
}.call(this); | ||
} | ||
incr() { | ||
if (this._length++ === 0) { | ||
return this.Events.trigger("leftzero"); | ||
} | ||
incr() { | ||
if (this._length++ === 0) { | ||
return this.Events.trigger("leftzero"); | ||
} | ||
} | ||
decr() { | ||
if (--this._length === 0) { | ||
return this.Events.trigger("zero"); | ||
} | ||
decr() { | ||
if (--this._length === 0) { | ||
return this.Events.trigger("zero"); | ||
} | ||
} | ||
push(priority, job) { | ||
return this._lists[priority].push(job); | ||
} | ||
push(priority, job) { | ||
return this._lists[priority].push(job); | ||
} | ||
queued(priority) { | ||
if (priority != null) { | ||
return this._lists[priority].length; | ||
} else { | ||
return this._length; | ||
} | ||
queued(priority) { | ||
if (priority != null) { | ||
return this._lists[priority].length; | ||
} else { | ||
return this._length; | ||
} | ||
} | ||
shiftAll(fn) { | ||
return this._lists.forEach(function (list) { | ||
return list.forEachShift(fn); | ||
}); | ||
} | ||
shiftAll(fn) { | ||
return this._lists.forEach(function (list) { | ||
return list.forEachShift(fn); | ||
}); | ||
} | ||
getFirst(arr = this._lists) { | ||
var j, len, list; | ||
for (j = 0, len = arr.length; j < len; j++) { | ||
list = arr[j]; | ||
if (list.length > 0) { | ||
return list; | ||
} | ||
getFirst(arr = this._lists) { | ||
var j, len, list; | ||
for (j = 0, len = arr.length; j < len; j++) { | ||
list = arr[j]; | ||
if (list.length > 0) { | ||
return list; | ||
} | ||
return []; | ||
} | ||
shiftLastFrom(priority) { | ||
return this.getFirst(this._lists.slice(priority).reverse()).shift(); | ||
} | ||
return []; | ||
} | ||
}; | ||
shiftLastFrom(priority) { | ||
return this.getFirst(this._lists.slice(priority).reverse()).shift(); | ||
} | ||
module.exports = Queues; | ||
}).call(undefined); | ||
}; | ||
module.exports = Queues; |
"use strict"; | ||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } | ||
(function () { | ||
var Events, RedisConnection, Scripts, parser; | ||
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } | ||
parser = require("./parser"); | ||
var Events, RedisConnection, Scripts, parser; | ||
parser = require("./parser"); | ||
Events = require("./Events"); | ||
Scripts = require("./Scripts"); | ||
Events = require("./Events"); | ||
RedisConnection = function () { | ||
class RedisConnection { | ||
constructor(options = {}) { | ||
var Redis; | ||
Redis = eval("require")("redis"); // Obfuscated or else Webpack/Angular will try to inline the optional redis module | ||
Scripts = require("./Scripts"); | ||
parser.load(options, this.defaults, this); | ||
RedisConnection = function () { | ||
class RedisConnection { | ||
constructor(options = {}) { | ||
var Redis; | ||
Redis = eval("require")("redis"); // Obfuscated or else Webpack/Angular will try to inline the optional redis module | ||
parser.load(options, this.defaults, this); | ||
if (this.Events == null) { | ||
this.Events = new Events(this); | ||
if (this.Events == null) { | ||
this.Events = new Events(this); | ||
} | ||
this.terminated = false; | ||
if (this.client == null) { | ||
this.client = Redis.createClient(this.clientOptions); | ||
} | ||
this.subscriber = this.client.duplicate(); | ||
this.limiters = {}; | ||
this.shas = {}; | ||
this.ready = this.Promise.all([this._setup(this.client, false), this._setup(this.subscriber, true)]).then(() => { | ||
return this._loadScripts(); | ||
}).then(() => { | ||
return { | ||
client: this.client, | ||
subscriber: this.subscriber | ||
}; | ||
}); | ||
} | ||
_setup(client, subscriber) { | ||
return new this.Promise((resolve, reject) => { | ||
client.on("error", e => { | ||
return this.Events.trigger("error", [e]); | ||
}); | ||
if (subscriber) { | ||
client.on("message", (channel, message) => { | ||
var ref; | ||
return (ref = this.limiters[channel]) != null ? ref._store.onMessage(message) : void 0; | ||
}); | ||
} | ||
this.terminated = false; | ||
if (this.client == null) { | ||
this.client = Redis.createClient(this.clientOptions); | ||
if (client.ready) { | ||
return resolve(); | ||
} else { | ||
return client.once("ready", resolve); | ||
} | ||
this.subscriber = this.client.duplicate(); | ||
this.limiters = {}; | ||
this.shas = {}; | ||
this.ready = this.Promise.all([this._setup(this.client, false), this._setup(this.subscriber, true)]).then(() => { | ||
return this._loadScripts(); | ||
}).then(() => { | ||
return { client: this.client, subscriber: this.subscriber }; | ||
}); | ||
} | ||
_loadScript(name) { | ||
return new this.Promise((resolve, reject) => { | ||
var payload; | ||
payload = Scripts.payload(name); | ||
return this.client.multi([["script", "load", payload]]).exec((err, replies) => { | ||
if (err != null) { | ||
return reject(err); | ||
} | ||
this.shas[name] = replies[0]; | ||
return resolve(replies[0]); | ||
}); | ||
} | ||
}); | ||
} | ||
_setup(client, subscriber) { | ||
return new this.Promise((resolve, reject) => { | ||
client.on("error", e => { | ||
return this.Events.trigger("error", [e]); | ||
}); | ||
if (subscriber) { | ||
client.on("message", (channel, message) => { | ||
var ref; | ||
return (ref = this.limiters[channel]) != null ? ref._store.onMessage(message) : void 0; | ||
}); | ||
} | ||
if (client.ready) { | ||
_loadScripts() { | ||
return this.Promise.all(Scripts.names.map(k => { | ||
return this._loadScript(k); | ||
})); | ||
} | ||
__addLimiter__(instance) { | ||
var channel; | ||
channel = instance.channel(); | ||
return new this.Promise((resolve, reject) => { | ||
var handler; | ||
handler = chan => { | ||
if (chan === channel) { | ||
this.subscriber.removeListener("subscribe", handler); | ||
this.limiters[channel] = instance; | ||
return resolve(); | ||
} else { | ||
return client.once("ready", resolve); | ||
} | ||
}); | ||
} | ||
}; | ||
_loadScript(name) { | ||
return new this.Promise((resolve, reject) => { | ||
var payload; | ||
payload = Scripts.payload(name); | ||
return this.client.multi([["script", "load", payload]]).exec((err, replies) => { | ||
if (err != null) { | ||
return reject(err); | ||
} | ||
this.shas[name] = replies[0]; | ||
return resolve(replies[0]); | ||
}); | ||
}); | ||
} | ||
this.subscriber.on("subscribe", handler); | ||
return this.subscriber.subscribe(channel); | ||
}); | ||
} | ||
_loadScripts() { | ||
return this.Promise.all(Scripts.names.map(k => { | ||
return this._loadScript(k); | ||
})); | ||
} | ||
__removeLimiter__(instance) { | ||
var _this = this; | ||
__addLimiter__(instance) { | ||
return _asyncToGenerator(function* () { | ||
var channel; | ||
channel = instance.channel(); | ||
return new this.Promise((resolve, reject) => { | ||
var handler; | ||
handler = chan => { | ||
if (chan === channel) { | ||
this.subscriber.removeListener("subscribe", handler); | ||
this.limiters[channel] = instance; | ||
return resolve(); | ||
} | ||
}; | ||
this.subscriber.on("subscribe", handler); | ||
return this.subscriber.subscribe(channel); | ||
}); | ||
} | ||
__removeLimiter__(instance) { | ||
var _this = this; | ||
if (!_this.terminated) { | ||
yield new _this.Promise((resolve, reject) => { | ||
return _this.subscriber.unsubscribe(channel, function (err, chan) { | ||
if (err != null) { | ||
return reject(err); | ||
} | ||
return _asyncToGenerator(function* () { | ||
var channel; | ||
channel = instance.channel(); | ||
if (!_this.terminated) { | ||
yield new _this.Promise(function (resolve, reject) { | ||
return _this.subscriber.unsubscribe(channel, function (err, chan) { | ||
if (err != null) { | ||
return reject(err); | ||
} | ||
if (chan === channel) { | ||
return resolve(); | ||
} | ||
}); | ||
if (chan === channel) { | ||
return resolve(); | ||
} | ||
}); | ||
} | ||
return delete _this.limiters[channel]; | ||
})(); | ||
} | ||
}); | ||
} | ||
__scriptArgs__(name, id, args, cb) { | ||
var keys; | ||
keys = Scripts.keys(name, id); | ||
return [this.shas[name], keys.length].concat(keys, args, cb); | ||
} | ||
return delete _this.limiters[channel]; | ||
})(); | ||
} | ||
__scriptFn__(name) { | ||
return this.client.evalsha.bind(this.client); | ||
} | ||
__scriptArgs__(name, id, args, cb) { | ||
var keys; | ||
keys = Scripts.keys(name, id); | ||
return [this.shas[name], keys.length].concat(keys, args, cb); | ||
} | ||
disconnect(flush = true) { | ||
var i, k, len, ref; | ||
ref = Object.keys(this.limiters); | ||
for (i = 0, len = ref.length; i < len; i++) { | ||
k = ref[i]; | ||
clearInterval(this.limiters[k]._store.heartbeat); | ||
} | ||
this.limiters = {}; | ||
this.terminated = true; | ||
this.client.end(flush); | ||
this.subscriber.end(flush); | ||
return this.Promise.resolve(); | ||
__scriptFn__(name) { | ||
return this.client.evalsha.bind(this.client); | ||
} | ||
disconnect(flush = true) { | ||
var i, k, len, ref; | ||
ref = Object.keys(this.limiters); | ||
for (i = 0, len = ref.length; i < len; i++) { | ||
k = ref[i]; | ||
clearInterval(this.limiters[k]._store.heartbeat); | ||
} | ||
}; | ||
this.limiters = {}; | ||
this.terminated = true; | ||
this.client.end(flush); | ||
this.subscriber.end(flush); | ||
return this.Promise.resolve(); | ||
} | ||
RedisConnection.prototype.datastore = "redis"; | ||
} | ||
RedisConnection.prototype.defaults = { | ||
clientOptions: {}, | ||
client: null, | ||
Promise: Promise, | ||
Events: null | ||
}; | ||
; | ||
RedisConnection.prototype.datastore = "redis"; | ||
RedisConnection.prototype.defaults = { | ||
clientOptions: {}, | ||
client: null, | ||
Promise: Promise, | ||
Events: null | ||
}; | ||
return RedisConnection; | ||
}.call(void 0); | ||
return RedisConnection; | ||
}.call(this); | ||
module.exports = RedisConnection; | ||
}).call(undefined); | ||
module.exports = RedisConnection; |
"use strict"; | ||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); | ||
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } | ||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } | ||
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } | ||
(function () { | ||
var BottleneckError, IORedisConnection, RedisConnection, RedisDatastore, parser; | ||
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } | ||
parser = require("./parser"); | ||
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } | ||
BottleneckError = require("./BottleneckError"); | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } | ||
RedisConnection = require("./RedisConnection"); | ||
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } | ||
IORedisConnection = require("./IORedisConnection"); | ||
var BottleneckError, IORedisConnection, RedisConnection, RedisDatastore, parser; | ||
parser = require("./parser"); | ||
BottleneckError = require("./BottleneckError"); | ||
RedisConnection = require("./RedisConnection"); | ||
IORedisConnection = require("./IORedisConnection"); | ||
RedisDatastore = class RedisDatastore { | ||
constructor(instance, storeOptions, storeInstanceOptions) { | ||
this.instance = instance; | ||
this.storeOptions = storeOptions; | ||
this.originalId = this.instance.id; | ||
parser.load(storeInstanceOptions, storeInstanceOptions, this); | ||
this.clients = {}; | ||
this.sharedConnection = this.connection != null; | ||
RedisDatastore = class RedisDatastore { | ||
constructor(instance, storeOptions, storeInstanceOptions) { | ||
this.instance = instance; | ||
this.storeOptions = storeOptions; | ||
this.originalId = this.instance.id; | ||
parser.load(storeInstanceOptions, storeInstanceOptions, this); | ||
this.clients = {}; | ||
this.sharedConnection = this.connection != null; | ||
if (this.connection == null) { | ||
this.connection = this.instance.datastore === "redis" ? new RedisConnection({ | ||
clientOptions: this.clientOptions, | ||
Promise: this.Promise, | ||
Events: this.instance.Events | ||
}) : this.instance.datastore === "ioredis" ? new IORedisConnection({ | ||
clientOptions: this.clientOptions, | ||
clusterNodes: this.clusterNodes, | ||
Promise: this.Promise, | ||
Events: this.instance.Events | ||
}) : void 0; | ||
} | ||
this.instance.connection = this.connection; | ||
this.instance.datastore = this.connection.datastore; | ||
this.ready = this.connection.ready.then(clients => { | ||
this.clients = clients; | ||
return this.runScript("init", this.prepareInitSettings(this.clearDatastore)); | ||
}).then(() => { | ||
return this.connection.__addLimiter__(this.instance); | ||
}).then(() => { | ||
var base; | ||
if (typeof (base = this.heartbeat = setInterval(() => { | ||
return this.runScript("heartbeat", []).catch(e => { | ||
return this.instance.Events.trigger("error", [e]); | ||
}); | ||
}, this.heartbeatInterval)).unref === "function") { | ||
base.unref(); | ||
} | ||
return this.clients; | ||
}); | ||
if (this.connection == null) { | ||
this.connection = this.instance.datastore === "redis" ? new RedisConnection({ | ||
clientOptions: this.clientOptions, | ||
Promise: this.Promise, | ||
Events: this.instance.Events | ||
}) : this.instance.datastore === "ioredis" ? new IORedisConnection({ | ||
clientOptions: this.clientOptions, | ||
clusterNodes: this.clusterNodes, | ||
Promise: this.Promise, | ||
Events: this.instance.Events | ||
}) : void 0; | ||
} | ||
__publish__(message) { | ||
var _this = this; | ||
this.instance.connection = this.connection; | ||
this.instance.datastore = this.connection.datastore; | ||
this.ready = this.connection.ready.then(clients => { | ||
this.clients = clients; | ||
return this.runScript("init", this.prepareInitSettings(this.clearDatastore)); | ||
}).then(() => { | ||
return this.connection.__addLimiter__(this.instance); | ||
}).then(() => { | ||
var base; | ||
return _asyncToGenerator(function* () { | ||
var client; | ||
if (typeof (base = this.heartbeat = setInterval(() => { | ||
return this.runScript("heartbeat", []).catch(e => { | ||
return this.instance.Events.trigger("error", [e]); | ||
}); | ||
}, this.heartbeatInterval)).unref === "function") { | ||
base.unref(); | ||
} | ||
var _ref = yield _this.ready; | ||
return this.clients; | ||
}); | ||
} | ||
client = _ref.client; | ||
__publish__(message) { | ||
var _this = this; | ||
return client.publish(_this.instance.channel(), `message:${message.toString()}`); | ||
})(); | ||
return _asyncToGenerator(function* () { | ||
var client; | ||
var _ref = yield _this.ready; | ||
client = _ref.client; | ||
return client.publish(_this.instance.channel(), `message:${message.toString()}`); | ||
})(); | ||
} | ||
onMessage(message) { | ||
var data, pos, type; | ||
pos = message.indexOf(":"); | ||
var _ref2 = [message.slice(0, pos), message.slice(pos + 1)]; | ||
type = _ref2[0]; | ||
data = _ref2[1]; | ||
if (type === "capacity") { | ||
return this.instance._drainAll(data.length > 0 ? ~~data : void 0); | ||
} else if (type === "message") { | ||
return this.instance.Events.trigger("message", [data]); | ||
} else if (type === "blocked") { | ||
return this.instance._dropAllQueued(); | ||
} | ||
} | ||
onMessage(message) { | ||
var data, pos, type; | ||
pos = message.indexOf(":"); | ||
var _ref2 = [message.slice(0, pos), message.slice(pos + 1)]; | ||
type = _ref2[0]; | ||
data = _ref2[1]; | ||
__disconnect__(flush) { | ||
clearInterval(this.heartbeat); | ||
if (type === "capacity") { | ||
return this.instance._drainAll(data.length > 0 ? ~~data : void 0); | ||
} else if (type === "message") { | ||
return this.instance.Events.trigger("message", [data]); | ||
} else if (type === "blocked") { | ||
return this.instance._dropAllQueued(); | ||
} | ||
if (this.sharedConnection) { | ||
return this.connection.__removeLimiter__(this.instance); | ||
} else { | ||
return this.connection.disconnect(flush); | ||
} | ||
} | ||
__disconnect__(flush) { | ||
clearInterval(this.heartbeat); | ||
if (this.sharedConnection) { | ||
return this.connection.__removeLimiter__(this.instance); | ||
} else { | ||
return this.connection.disconnect(flush); | ||
runScript(name, args) { | ||
var _this2 = this; | ||
return _asyncToGenerator(function* () { | ||
if (!(name === "init" || name === "heartbeat")) { | ||
yield _this2.ready; | ||
} | ||
} | ||
runScript(name, args) { | ||
var _this2 = this; | ||
args.unshift(Date.now().toString()); | ||
return new _this2.Promise((resolve, reject) => { | ||
var arr; | ||
return _asyncToGenerator(function* () { | ||
if (!(name === "init" || name === "heartbeat")) { | ||
yield _this2.ready; | ||
} | ||
args.unshift(Date.now().toString()); | ||
return new _this2.Promise(function (resolve, reject) { | ||
var arr; | ||
_this2.instance.Events.trigger("debug", [`Calling Redis script: ${name}.lua`, args]); | ||
arr = _this2.connection.__scriptArgs__(name, _this2.originalId, args, function (err, replies) { | ||
if (err != null) { | ||
return reject(err); | ||
} | ||
return resolve(replies); | ||
}); | ||
return _this2.connection.__scriptFn__(name).apply({}, arr); | ||
}).catch(function (e) { | ||
if (e.message === "SETTINGS_KEY_NOT_FOUND") { | ||
return _this2.runScript("init", _this2.prepareInitSettings(false)).then(function () { | ||
return _this2.runScript(name, args); | ||
}); | ||
} else { | ||
return _this2.Promise.reject(e); | ||
_this2.instance.Events.trigger("debug", [`Calling Redis script: ${name}.lua`, args]); | ||
arr = _this2.connection.__scriptArgs__(name, _this2.originalId, args, function (err, replies) { | ||
if (err != null) { | ||
return reject(err); | ||
} | ||
return resolve(replies); | ||
}); | ||
})(); | ||
} | ||
return _this2.connection.__scriptFn__(name).apply({}, arr); | ||
}).catch(e => { | ||
if (e.message === "SETTINGS_KEY_NOT_FOUND") { | ||
return _this2.runScript("init", _this2.prepareInitSettings(false)).then(() => { | ||
return _this2.runScript(name, args); | ||
}); | ||
} else { | ||
return _this2.Promise.reject(e); | ||
} | ||
}); | ||
})(); | ||
} | ||
prepareArray(arr) { | ||
var i, len, results, x; | ||
results = []; | ||
for (i = 0, len = arr.length; i < len; i++) { | ||
x = arr[i]; | ||
results.push(x != null ? x.toString() : ""); | ||
} | ||
return results; | ||
} | ||
prepareArray(arr) { | ||
var i, len, results, x; | ||
results = []; | ||
prepareObject(obj) { | ||
var arr, k, v; | ||
arr = []; | ||
for (k in obj) { | ||
v = obj[k]; | ||
arr.push(k, v != null ? v.toString() : ""); | ||
} | ||
return arr; | ||
for (i = 0, len = arr.length; i < len; i++) { | ||
x = arr[i]; | ||
results.push(x != null ? x.toString() : ""); | ||
} | ||
prepareInitSettings(clear) { | ||
var args; | ||
args = this.prepareObject(Object.assign({}, this.storeOptions, { | ||
id: this.originalId, | ||
version: this.instance.version, | ||
groupTimeout: this.timeout | ||
})); | ||
args.unshift(clear ? 1 : 0, this.instance.version); | ||
return args; | ||
} | ||
return results; | ||
} | ||
convertBool(b) { | ||
return !!b; | ||
prepareObject(obj) { | ||
var arr, k, v; | ||
arr = []; | ||
for (k in obj) { | ||
v = obj[k]; | ||
arr.push(k, v != null ? v.toString() : ""); | ||
} | ||
__updateSettings__(options) { | ||
var _this3 = this; | ||
return arr; | ||
} | ||
return _asyncToGenerator(function* () { | ||
yield _this3.runScript("update_settings", _this3.prepareObject(options)); | ||
return parser.overwrite(options, options, _this3.storeOptions); | ||
})(); | ||
} | ||
prepareInitSettings(clear) { | ||
var args; | ||
args = this.prepareObject(Object.assign({}, this.storeOptions, { | ||
id: this.originalId, | ||
version: this.instance.version, | ||
groupTimeout: this.timeout | ||
})); | ||
args.unshift(clear ? 1 : 0, this.instance.version); | ||
return args; | ||
} | ||
__running__() { | ||
return this.runScript("running", []); | ||
} | ||
convertBool(b) { | ||
return !!b; | ||
} | ||
__done__() { | ||
return this.runScript("done", []); | ||
} | ||
__updateSettings__(options) { | ||
var _this3 = this; | ||
__groupCheck__() { | ||
var _this4 = this; | ||
return _asyncToGenerator(function* () { | ||
yield _this3.runScript("update_settings", _this3.prepareObject(options)); | ||
return parser.overwrite(options, options, _this3.storeOptions); | ||
})(); | ||
} | ||
return _asyncToGenerator(function* () { | ||
return _this4.convertBool((yield _this4.runScript("group_check", []))); | ||
})(); | ||
} | ||
__running__() { | ||
return this.runScript("running", []); | ||
} | ||
__incrementReservoir__(incr) { | ||
return this.runScript("increment_reservoir", [incr]); | ||
} | ||
__done__() { | ||
return this.runScript("done", []); | ||
} | ||
__currentReservoir__() { | ||
return this.runScript("current_reservoir", []); | ||
} | ||
__groupCheck__() { | ||
var _this4 = this; | ||
__check__(weight) { | ||
var _this5 = this; | ||
return _asyncToGenerator(function* () { | ||
return _this4.convertBool((yield _this4.runScript("group_check", []))); | ||
})(); | ||
} | ||
return _asyncToGenerator(function* () { | ||
return _this5.convertBool((yield _this5.runScript("check", _this5.prepareArray([weight])))); | ||
})(); | ||
} | ||
__incrementReservoir__(incr) { | ||
return this.runScript("increment_reservoir", [incr]); | ||
} | ||
__register__(index, weight, expiration) { | ||
var _this6 = this; | ||
__currentReservoir__() { | ||
return this.runScript("current_reservoir", []); | ||
} | ||
return _asyncToGenerator(function* () { | ||
var reservoir, success, wait; | ||
__check__(weight) { | ||
var _this5 = this; | ||
var _ref3 = yield _this6.runScript("register", _this6.prepareArray([index, weight, expiration])); | ||
return _asyncToGenerator(function* () { | ||
return _this5.convertBool((yield _this5.runScript("check", _this5.prepareArray([weight])))); | ||
})(); | ||
} | ||
var _ref4 = _slicedToArray(_ref3, 3); | ||
__register__(index, weight, expiration) { | ||
var _this6 = this; | ||
success = _ref4[0]; | ||
wait = _ref4[1]; | ||
reservoir = _ref4[2]; | ||
return _asyncToGenerator(function* () { | ||
var reservoir, success, wait; | ||
return { | ||
success: _this6.convertBool(success), | ||
wait, | ||
reservoir | ||
}; | ||
})(); | ||
} | ||
var _ref3 = yield _this6.runScript("register", _this6.prepareArray([index, weight, expiration])); | ||
__submit__(queueLength, weight) { | ||
var _this7 = this; | ||
var _ref4 = _slicedToArray(_ref3, 3); | ||
return _asyncToGenerator(function* () { | ||
var blocked, e, maxConcurrent, overweight, reachedHWM, strategy; | ||
try { | ||
var _ref5 = yield _this7.runScript("submit", _this7.prepareArray([queueLength, weight])); | ||
success = _ref4[0]; | ||
wait = _ref4[1]; | ||
reservoir = _ref4[2]; | ||
return { | ||
success: _this6.convertBool(success), | ||
wait, | ||
reservoir | ||
}; | ||
})(); | ||
} | ||
var _ref6 = _slicedToArray(_ref5, 3); | ||
__submit__(queueLength, weight) { | ||
var _this7 = this; | ||
reachedHWM = _ref6[0]; | ||
blocked = _ref6[1]; | ||
strategy = _ref6[2]; | ||
return _asyncToGenerator(function* () { | ||
var blocked, e, maxConcurrent, overweight, reachedHWM, strategy; | ||
return { | ||
reachedHWM: _this7.convertBool(reachedHWM), | ||
blocked: _this7.convertBool(blocked), | ||
strategy | ||
}; | ||
} catch (error) { | ||
e = error; | ||
if (e.message.indexOf("OVERWEIGHT") === 0) { | ||
var _e$message$split = e.message.split(":"); | ||
try { | ||
var _ref5 = yield _this7.runScript("submit", _this7.prepareArray([queueLength, weight])); | ||
var _e$message$split2 = _slicedToArray(_e$message$split, 3); | ||
var _ref6 = _slicedToArray(_ref5, 3); | ||
overweight = _e$message$split2[0]; | ||
weight = _e$message$split2[1]; | ||
maxConcurrent = _e$message$split2[2]; | ||
reachedHWM = _ref6[0]; | ||
blocked = _ref6[1]; | ||
strategy = _ref6[2]; | ||
return { | ||
reachedHWM: _this7.convertBool(reachedHWM), | ||
blocked: _this7.convertBool(blocked), | ||
strategy | ||
}; | ||
} catch (error) { | ||
e = error; | ||
throw new BottleneckError(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${maxConcurrent}`); | ||
} else { | ||
throw e; | ||
} | ||
if (e.message.indexOf("OVERWEIGHT") === 0) { | ||
var _e$message$split = e.message.split(":"); | ||
var _e$message$split2 = _slicedToArray(_e$message$split, 3); | ||
overweight = _e$message$split2[0]; | ||
weight = _e$message$split2[1]; | ||
maxConcurrent = _e$message$split2[2]; | ||
throw new BottleneckError(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${maxConcurrent}`); | ||
} else { | ||
throw e; | ||
} | ||
})(); | ||
} | ||
} | ||
})(); | ||
} | ||
__free__(index, weight) { | ||
var _this8 = this; | ||
__free__(index, weight) { | ||
var _this8 = this; | ||
return _asyncToGenerator(function* () { | ||
var running; | ||
running = yield _this8.runScript("free", _this8.prepareArray([index])); | ||
return { running }; | ||
})(); | ||
} | ||
return _asyncToGenerator(function* () { | ||
var running; | ||
running = yield _this8.runScript("free", _this8.prepareArray([index])); | ||
return { | ||
running | ||
}; | ||
})(); | ||
} | ||
}; | ||
module.exports = RedisDatastore; | ||
}).call(undefined); | ||
}; | ||
module.exports = RedisDatastore; |
"use strict"; | ||
(function () { | ||
var libraries, lua, templates; | ||
lua = require("./lua.json"); | ||
libraries = { | ||
get_time: lua["get_time.lua"], | ||
refresh_capacity: lua["refresh_capacity.lua"], | ||
conditions_check: lua["conditions_check.lua"], | ||
refresh_expiration: lua["refresh_expiration.lua"], | ||
validate_keys: lua["validate_keys.lua"] | ||
}; | ||
templates = { | ||
init: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
libs: ["refresh_capacity", "refresh_expiration"], | ||
code: lua["init.lua"] | ||
var libraries, lua, templates; | ||
lua = require("./lua.json"); | ||
libraries = { | ||
get_time: lua["get_time.lua"], | ||
refresh_capacity: lua["refresh_capacity.lua"], | ||
conditions_check: lua["conditions_check.lua"], | ||
refresh_expiration: lua["refresh_expiration.lua"], | ||
validate_keys: lua["validate_keys.lua"] | ||
}; | ||
templates = { | ||
init: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
heartbeat: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
libs: ["validate_keys", "refresh_capacity"], | ||
code: lua["heartbeat.lua"] | ||
libs: ["refresh_capacity", "refresh_expiration"], | ||
code: lua["init.lua"] | ||
}, | ||
heartbeat: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
update_settings: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
libs: ["validate_keys", "refresh_capacity", "refresh_expiration"], | ||
code: lua["update_settings.lua"] | ||
libs: ["validate_keys", "refresh_capacity"], | ||
code: lua["heartbeat.lua"] | ||
}, | ||
update_settings: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
running: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
libs: ["validate_keys", "refresh_capacity"], | ||
code: lua["running.lua"] | ||
libs: ["validate_keys", "refresh_capacity", "refresh_expiration"], | ||
code: lua["update_settings.lua"] | ||
}, | ||
running: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
done: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
libs: ["validate_keys", "refresh_capacity"], | ||
code: lua["done.lua"] | ||
libs: ["validate_keys", "refresh_capacity"], | ||
code: lua["running.lua"] | ||
}, | ||
done: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
group_check: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`]; | ||
}, | ||
libs: [], | ||
code: lua["group_check.lua"] | ||
libs: ["validate_keys", "refresh_capacity"], | ||
code: lua["done.lua"] | ||
}, | ||
group_check: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`]; | ||
}, | ||
check: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
libs: ["validate_keys", "refresh_capacity", "conditions_check"], | ||
code: lua["check.lua"] | ||
libs: [], | ||
code: lua["group_check.lua"] | ||
}, | ||
check: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
submit: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
libs: ["validate_keys", "refresh_capacity", "conditions_check", "refresh_expiration"], | ||
code: lua["submit.lua"] | ||
libs: ["validate_keys", "refresh_capacity", "conditions_check"], | ||
code: lua["check.lua"] | ||
}, | ||
submit: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
register: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
libs: ["validate_keys", "refresh_capacity", "conditions_check", "refresh_expiration"], | ||
code: lua["register.lua"] | ||
libs: ["validate_keys", "refresh_capacity", "conditions_check", "refresh_expiration"], | ||
code: lua["submit.lua"] | ||
}, | ||
register: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
free: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
libs: ["validate_keys", "refresh_capacity"], | ||
code: lua["free.lua"] | ||
libs: ["validate_keys", "refresh_capacity", "conditions_check", "refresh_expiration"], | ||
code: lua["register.lua"] | ||
}, | ||
free: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
current_reservoir: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`]; | ||
}, | ||
libs: ["validate_keys"], | ||
code: lua["current_reservoir.lua"] | ||
libs: ["validate_keys", "refresh_capacity"], | ||
code: lua["free.lua"] | ||
}, | ||
current_reservoir: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`]; | ||
}, | ||
increment_reservoir: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
libs: ["validate_keys", "refresh_capacity", "refresh_expiration"], | ||
code: lua["increment_reservoir.lua"] | ||
} | ||
}; | ||
libs: ["validate_keys"], | ||
code: lua["current_reservoir.lua"] | ||
}, | ||
increment_reservoir: { | ||
keys: function keys(id) { | ||
return [`b_${id}_settings`, `b_${id}_running`, `b_${id}_executing`]; | ||
}, | ||
libs: ["validate_keys", "refresh_capacity", "refresh_expiration"], | ||
code: lua["increment_reservoir.lua"] | ||
} | ||
}; | ||
exports.names = Object.keys(templates); | ||
exports.names = Object.keys(templates); | ||
exports.keys = function (name, id) { | ||
return templates[name].keys(id); | ||
}; | ||
exports.keys = function (name, id) { | ||
return templates[name].keys(id); | ||
}; | ||
exports.payload = function (name) { | ||
return templates[name].libs.map(function (lib) { | ||
return libraries[lib]; | ||
}).join("\n") + templates[name].code; | ||
}; | ||
}).call(undefined); | ||
exports.payload = function (name) { | ||
return templates[name].libs.map(function (lib) { | ||
return libraries[lib]; | ||
}).join("\n") + templates[name].code; | ||
}; |
"use strict"; | ||
(function () { | ||
var BottleneckError, States; | ||
var BottleneckError, States; | ||
BottleneckError = require("./BottleneckError"); | ||
States = class States { | ||
constructor(status1) { | ||
this.status = status1; | ||
this.jobs = {}; | ||
this.counts = this.status.map(function () { | ||
return 0; | ||
}); | ||
} | ||
BottleneckError = require("./BottleneckError"); | ||
next(id) { | ||
var current, next; | ||
current = this.jobs[id]; | ||
next = current + 1; | ||
States = class States { | ||
constructor(status1) { | ||
this.status = status1; | ||
this.jobs = {}; | ||
this.counts = this.status.map(function () { | ||
return 0; | ||
}); | ||
if (current != null && next < this.status.length) { | ||
this.counts[current]--; | ||
this.counts[next]++; | ||
return this.jobs[id]++; | ||
} else if (current != null) { | ||
this.counts[current]--; | ||
return delete this.jobs[id]; | ||
} | ||
} | ||
next(id) { | ||
var current, next; | ||
current = this.jobs[id]; | ||
next = current + 1; | ||
if (current != null && next < this.status.length) { | ||
this.counts[current]--; | ||
this.counts[next]++; | ||
return this.jobs[id]++; | ||
} else if (current != null) { | ||
this.counts[current]--; | ||
return delete this.jobs[id]; | ||
} | ||
} | ||
start(id, initial = 0) { | ||
this.jobs[id] = initial; | ||
return this.counts[initial]++; | ||
} | ||
start(id, initial = 0) { | ||
this.jobs[id] = initial; | ||
return this.counts[initial]++; | ||
remove(id) { | ||
var current; | ||
current = this.jobs[id]; | ||
if (current != null) { | ||
this.counts[current]--; | ||
delete this.jobs[id]; | ||
} | ||
remove(id) { | ||
var current; | ||
current = this.jobs[id]; | ||
if (current != null) { | ||
this.counts[current]--; | ||
delete this.jobs[id]; | ||
return current != null; | ||
} | ||
jobStatus(id) { | ||
var ref; | ||
return (ref = this.status[this.jobs[id]]) != null ? ref : null; | ||
} | ||
statusJobs(status) { | ||
var index, k, ref, results, v; | ||
if (status != null) { | ||
index = this.status.indexOf(status); | ||
if (index < 0) { | ||
throw new BottleneckError(`status must be one of ${this.status.join(', ')}`); | ||
} | ||
return current != null; | ||
} | ||
jobStatus(id) { | ||
var ref; | ||
return (ref = this.status[this.jobs[id]]) != null ? ref : null; | ||
} | ||
ref = this.jobs; | ||
results = []; | ||
statusJobs(status) { | ||
var index, k, ref, results, v; | ||
if (status != null) { | ||
index = this.status.indexOf(status); | ||
if (index < 0) { | ||
throw new BottleneckError(`status must be one of ${this.status.join(', ')}`); | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (v === index) { | ||
results.push(k); | ||
} | ||
ref = this.jobs; | ||
results = []; | ||
for (k in ref) { | ||
v = ref[k]; | ||
if (v === index) { | ||
results.push(k); | ||
} | ||
} | ||
return results; | ||
} else { | ||
return Object.keys(this.jobs); | ||
} | ||
} | ||
statusCounts() { | ||
return this.counts.reduce((acc, v, i) => { | ||
acc[this.status[i]] = v; | ||
return acc; | ||
}, {}); | ||
return results; | ||
} else { | ||
return Object.keys(this.jobs); | ||
} | ||
} | ||
}; | ||
statusCounts() { | ||
return this.counts.reduce((acc, v, i) => { | ||
acc[this.status[i]] = v; | ||
return acc; | ||
}, {}); | ||
} | ||
module.exports = States; | ||
}).call(undefined); | ||
}; | ||
module.exports = States; |
128
lib/Sync.js
"use strict"; | ||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); | ||
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } | ||
function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } | ||
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } | ||
(function () { | ||
var DLList, | ||
Sync, | ||
splice = [].splice; | ||
function _toArray(arr) { return _arrayWithHoles(arr) || _iterableToArray(arr) || _nonIterableRest(); } | ||
DLList = require("./DLList"); | ||
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } | ||
Sync = class Sync { | ||
constructor(name, instance) { | ||
this.submit = this.submit.bind(this); | ||
this.name = name; | ||
this.instance = instance; | ||
this._running = 0; | ||
this._queue = new DLList(); | ||
} | ||
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } | ||
isEmpty() { | ||
return this._queue.length === 0; | ||
} | ||
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } | ||
_tryToRun() { | ||
var next; | ||
if (this._running < 1 && this._queue.length > 0) { | ||
this._running++; | ||
next = this._queue.shift(); | ||
return next.task.apply({}, next.args.concat((...args) => { | ||
var ref; | ||
this._running--; | ||
this._tryToRun(); | ||
return (ref = next.cb) != null ? ref.apply({}, args) : void 0; | ||
})); | ||
} | ||
} | ||
var DLList, | ||
Sync, | ||
splice = [].splice; | ||
DLList = require("./DLList"); | ||
Sync = class Sync { | ||
constructor(name, instance) { | ||
this.submit = this.submit.bind(this); | ||
this.name = name; | ||
this.instance = instance; | ||
this._running = 0; | ||
this._queue = new DLList(); | ||
} | ||
submit(task, ...args) { | ||
var _ref, _ref2, _splice$call, _splice$call2; | ||
isEmpty() { | ||
return this._queue.length === 0; | ||
} | ||
var cb, ref; | ||
ref = args, (_ref = ref, _ref2 = _toArray(_ref), args = _ref2.slice(0), _ref), (_splice$call = splice.call(args, -1), _splice$call2 = _slicedToArray(_splice$call, 1), cb = _splice$call2[0], _splice$call); | ||
this._queue.push({ task, args, cb }); | ||
return this._tryToRun(); | ||
_tryToRun() { | ||
var next; | ||
if (this._running < 1 && this._queue.length > 0) { | ||
this._running++; | ||
next = this._queue.shift(); | ||
return next.task.apply({}, next.args.concat((...args) => { | ||
var ref; | ||
this._running--; | ||
this._tryToRun(); | ||
return (ref = next.cb) != null ? ref.apply({}, args) : void 0; | ||
})); | ||
} | ||
} | ||
schedule(task, ...args) { | ||
var wrapped; | ||
wrapped = function wrapped(...args) { | ||
var _ref3, _ref4, _splice$call3, _splice$call4; | ||
submit(task, ...args) { | ||
var _ref, _ref2, _splice$call, _splice$call2; | ||
var cb, ref; | ||
ref = args, (_ref3 = ref, _ref4 = _toArray(_ref3), args = _ref4.slice(0), _ref3), (_splice$call3 = splice.call(args, -1), _splice$call4 = _slicedToArray(_splice$call3, 1), cb = _splice$call4[0], _splice$call3); | ||
return task.apply({}, args).then(function (...args) { | ||
return cb.apply({}, Array.prototype.concat(null, args)); | ||
}).catch(function (...args) { | ||
return cb.apply({}, args); | ||
}); | ||
}; | ||
return new this.instance.Promise((resolve, reject) => { | ||
return this.submit.apply({}, Array.prototype.concat(wrapped, args, function (...args) { | ||
return (args[0] != null ? reject : (args.shift(), resolve)).apply({}, args); | ||
})); | ||
var cb, ref; | ||
ref = args, (_ref = ref, _ref2 = _toArray(_ref), args = _ref2.slice(0), _ref), (_splice$call = splice.call(args, -1), _splice$call2 = _slicedToArray(_splice$call, 1), cb = _splice$call2[0], _splice$call); | ||
this._queue.push({ | ||
task, | ||
args, | ||
cb | ||
}); | ||
return this._tryToRun(); | ||
} | ||
schedule(task, ...args) { | ||
var wrapped; | ||
wrapped = function wrapped(...args) { | ||
var _ref3, _ref4, _splice$call3, _splice$call4; | ||
var cb, ref; | ||
ref = args, (_ref3 = ref, _ref4 = _toArray(_ref3), args = _ref4.slice(0), _ref3), (_splice$call3 = splice.call(args, -1), _splice$call4 = _slicedToArray(_splice$call3, 1), cb = _splice$call4[0], _splice$call3); | ||
return task.apply({}, args).then(function (...args) { | ||
return cb.apply({}, Array.prototype.concat(null, args)); | ||
}).catch(function (...args) { | ||
return cb.apply({}, args); | ||
}); | ||
} | ||
}; | ||
}; | ||
return new this.instance.Promise((resolve, reject) => { | ||
return this.submit.apply({}, Array.prototype.concat(wrapped, args, function (...args) { | ||
return (args[0] != null ? reject : (args.shift(), resolve)).apply({}, args); | ||
})); | ||
}); | ||
} | ||
module.exports = Sync; | ||
}).call(undefined); | ||
}; | ||
module.exports = Sync; |
{ | ||
"name": "bottleneck", | ||
"version": "2.12.2", | ||
"version": "2.13.0", | ||
"description": "Distributed task scheduler and rate limiter", | ||
@@ -9,4 +9,3 @@ "main": "lib/index.js", | ||
"test": "./node_modules/mocha/bin/mocha test", | ||
"build": "./scripts/build.sh", | ||
"compile": "./scripts/build.sh compile" | ||
"test-all": "DATASTORE=ioredis npm test && DATASTORE=redis npm test && BUILD=bundle npm test && npm test" | ||
}, | ||
@@ -27,4 +26,5 @@ "repository": { | ||
"throttling", | ||
"throttler", | ||
"load", | ||
"ddos" | ||
"clustering" | ||
], | ||
@@ -39,7 +39,6 @@ "author": { | ||
"devDependencies": { | ||
"@babel/core": "^7.1.2", | ||
"@babel/preset-env": "7.1.x", | ||
"@types/es6-promise": "0.0.33", | ||
"assert": "1.4.x", | ||
"babel-core": "^6.26.0", | ||
"babel-preset-env": "^1.6.1", | ||
"browserify": "*", | ||
"coffeescript": "2.3.x", | ||
@@ -50,6 +49,11 @@ "ejs-cli": "2.0.1", | ||
"redis": "^2.8.0", | ||
"typescript": "^2.6.2", | ||
"uglify-es": "3.x" | ||
"regenerator-runtime": "^0.12.1", | ||
"rollup": "^0.66.6", | ||
"rollup-plugin-babel": "4.0.x", | ||
"rollup-plugin-commonjs": "^9.2.0", | ||
"rollup-plugin-json": "^3.1.0", | ||
"rollup-plugin-node-resolve": "^3.4.0", | ||
"typescript": "^2.6.2" | ||
}, | ||
"dependencies": {} | ||
} |
@@ -14,6 +14,4 @@ # bottleneck | ||
Bottleneck v2 targets **Node 6+** and modern browsers. [Use Babel](https://github.com/SGrondin/bottleneck/issues/81) in your project if you must support older platforms. | ||
**[Upgrading from version 1?](#upgrading-to-v2)** | ||
Bottleneck v1 is compatible with any browser or Node version. It's still maintained, but it will not be receiving any new features. The v1 documentation is [here](https://github.com/SGrondin/bottleneck/tree/version-1). **[Upgrading from version 1?](#upgrading-to-v2)** | ||
## Install | ||
@@ -24,7 +22,10 @@ | ||
``` | ||
Not using npm? Import the `bottleneck.min.js` file. | ||
## Quick Start | ||
**Note:** To support older browsers and Node <6.0, you must import the ES5 bundle instead. | ||
```js | ||
import Bottleneck from "bottleneck/es5"; | ||
``` | ||
### Step 1 of 3 | ||
@@ -129,4 +130,6 @@ | ||
##### Gotchas | ||
#### Gotchas | ||
* Bottleneck requires Node 6+ to function. However, an ES5 build is included: `import Bottleneck from "bottleneck/es5";`. | ||
* Make sure you're catching `"error"` events emitted by your limiters! | ||
@@ -788,3 +791,3 @@ | ||
All the breaking changes: | ||
- Bottleneck v2 requires Node 6+ or a modern browser. Use Babel if you must support legacy platforms. Bottleneck v1 will continue to use ES5 only. | ||
- Bottleneck v2 requires Node 6+ or a modern browser. Use `require("bottleneck/es5")` if you need ES5 support in v2. Bottleneck v1 will continue to use ES5 only. | ||
- The Bottleneck constructor now takes an options object. See [Constructor](#constructor). | ||
@@ -825,3 +828,3 @@ - The `Cluster` feature is now called `Group`. This is to distinguish it from the new v2 [Clustering](#clustering) feature. | ||
The tests must also pass in Clustering mode. You'll need a Redis server running on `127.0.0.1:6379`, then run `./scripts/build.sh && DATASTORE=redis npm test && DATASTORE=ioredis npm test`. | ||
The tests must also pass in Clustering mode and using the ES5 bundle. You'll need a Redis server running on `127.0.0.1:6379`, then run `./scripts/build.sh && npm run test-all`. | ||
@@ -828,0 +831,0 @@ All contributions are appreciated and will be considered. |
var makeTest = require('./context') | ||
var Bottleneck = require('../lib/index.js') | ||
var Bottleneck = require('./bottleneck') | ||
var assert = require('assert') | ||
@@ -205,3 +205,3 @@ | ||
.then(function (results) { | ||
c.checkDuration(85, 20) | ||
c.checkDuration(85, 25) | ||
c.mustEqual(batches, [[1, 2, 3], [4, 5]]) | ||
@@ -208,0 +208,0 @@ }) |
var makeTest = require('./context') | ||
var Bottleneck = require('../lib/index.js') | ||
var Bottleneck = require('./bottleneck') | ||
var Scripts = require('../lib/Scripts.js') | ||
@@ -4,0 +4,0 @@ var assert = require('assert') |
global.TEST = true | ||
var Bottleneck = require('../lib/index.js') | ||
var Bottleneck = require('./bottleneck') | ||
var assert = require('assert') | ||
@@ -4,0 +4,0 @@ |
var makeTest = require('./context') | ||
var Bottleneck = require('../lib/index.js') | ||
var Bottleneck = require('./bottleneck') | ||
var assert = require('assert') | ||
@@ -4,0 +4,0 @@ var child_process = require('child_process') |
var makeTest = require('./context') | ||
var Bottleneck = require('../lib/index.js') | ||
var Bottleneck = require('./bottleneck') | ||
var assert = require('assert') | ||
@@ -4,0 +4,0 @@ |
var makeTest = require('./context') | ||
var Bottleneck = require('../lib/index.js') | ||
var Bottleneck = require('./bottleneck') | ||
var assert = require('assert') | ||
@@ -25,3 +25,3 @@ var Redis = require('ioredis') | ||
c.mustEqual(c.limiter.datastore, 'ioredis') | ||
c.mustEqual(c.limiter._store.connection.client.nodes().length, 1) | ||
assert(c.limiter._store.connection.client.nodes().length >= 0) | ||
}) | ||
@@ -28,0 +28,0 @@ |
var makeTest = require('./context') | ||
var Bottleneck = require('../lib/index.js') | ||
var Bottleneck = require('./bottleneck') | ||
var assert = require('assert') | ||
@@ -4,0 +4,0 @@ var Redis = require('redis') |
var makeTest = require('./context') | ||
var Bottleneck = require('../lib/index.js') | ||
var Bottleneck = require('./bottleneck') | ||
var assert = require('assert') | ||
@@ -4,0 +4,0 @@ |
var makeTest = require('./context') | ||
var Bottleneck = require('../lib/index.js') | ||
var Bottleneck = require('./bottleneck') | ||
var assert = require('assert') | ||
@@ -4,0 +4,0 @@ |
@@ -1,2 +0,2 @@ | ||
var Bottleneck = require('../../lib/index.js') | ||
var Bottleneck = require('../bottleneck.js') | ||
var now = Date.now() | ||
@@ -3,0 +3,0 @@ |
var States = require('../lib/States') | ||
var assert = require('assert') | ||
var c = require('./context')({datastore: 'local'}) | ||
var Bottleneck = require('../lib/index.js') | ||
var Bottleneck = require('./bottleneck') | ||
@@ -97,3 +97,5 @@ describe('States', function () { | ||
} catch (err) { | ||
assert(err instanceof Bottleneck.BottleneckError) | ||
if (process.env.BUILD !== 'bundle') { | ||
assert(err instanceof Bottleneck.BottleneckError) | ||
} | ||
done() | ||
@@ -100,0 +102,0 @@ } |
var makeTest = require('./context') | ||
var Bottleneck = require('../lib/index.js') | ||
var Bottleneck = require('./bottleneck') | ||
var assert = require('assert') | ||
@@ -4,0 +4,0 @@ |
Sorry, the diff of this file is not supported yet
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
79
8885
1
834
43
4
452553
16