287 lines
8.2 KiB
JavaScript
287 lines
8.2 KiB
JavaScript
"use strict";
|
|
|
|
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 _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); }); }; }
|
|
|
|
var BottleneckError, LocalDatastore, parser;
|
|
parser = require("./parser");
|
|
BottleneckError = require("./BottleneckError");
|
|
LocalDatastore = class LocalDatastore {
|
|
constructor(instance, storeOptions, storeInstanceOptions) {
|
|
this.instance = instance;
|
|
this.storeOptions = storeOptions;
|
|
this.clientId = this.instance._randomIndex();
|
|
parser.load(storeInstanceOptions, storeInstanceOptions, this);
|
|
this._nextRequest = this._lastReservoirRefresh = this._lastReservoirIncrease = Date.now();
|
|
this._running = 0;
|
|
this._done = 0;
|
|
this._unblockTime = 0;
|
|
this.ready = this.Promise.resolve();
|
|
this.clients = {};
|
|
|
|
this._startHeartbeat();
|
|
}
|
|
|
|
_startHeartbeat() {
|
|
var base;
|
|
|
|
if (this.heartbeat == null && (this.storeOptions.reservoirRefreshInterval != null && this.storeOptions.reservoirRefreshAmount != null || this.storeOptions.reservoirIncreaseInterval != null && this.storeOptions.reservoirIncreaseAmount != null)) {
|
|
return typeof (base = this.heartbeat = setInterval(() => {
|
|
var amount, incr, maximum, now, reservoir;
|
|
now = Date.now();
|
|
|
|
if (this.storeOptions.reservoirRefreshInterval != null && now >= this._lastReservoirRefresh + this.storeOptions.reservoirRefreshInterval) {
|
|
this._lastReservoirRefresh = now;
|
|
this.storeOptions.reservoir = this.storeOptions.reservoirRefreshAmount;
|
|
|
|
this.instance._drainAll(this.computeCapacity());
|
|
}
|
|
|
|
if (this.storeOptions.reservoirIncreaseInterval != null && now >= this._lastReservoirIncrease + this.storeOptions.reservoirIncreaseInterval) {
|
|
var _this$storeOptions = this.storeOptions;
|
|
amount = _this$storeOptions.reservoirIncreaseAmount;
|
|
maximum = _this$storeOptions.reservoirIncreaseMaximum;
|
|
reservoir = _this$storeOptions.reservoir;
|
|
this._lastReservoirIncrease = now;
|
|
incr = maximum != null ? Math.min(amount, maximum - reservoir) : amount;
|
|
|
|
if (incr > 0) {
|
|
this.storeOptions.reservoir += incr;
|
|
return this.instance._drainAll(this.computeCapacity());
|
|
}
|
|
}
|
|
}, this.heartbeatInterval)).unref === "function" ? base.unref() : void 0;
|
|
} else {
|
|
return clearInterval(this.heartbeat);
|
|
}
|
|
}
|
|
|
|
__publish__(message) {
|
|
var _this = this;
|
|
|
|
return _asyncToGenerator(function* () {
|
|
yield _this.yieldLoop();
|
|
return _this.instance.Events.trigger("message", message.toString());
|
|
})();
|
|
}
|
|
|
|
__disconnect__(flush) {
|
|
var _this2 = this;
|
|
|
|
return _asyncToGenerator(function* () {
|
|
yield _this2.yieldLoop();
|
|
clearInterval(_this2.heartbeat);
|
|
return _this2.Promise.resolve();
|
|
})();
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
__updateSettings__(options) {
|
|
var _this3 = this;
|
|
|
|
return _asyncToGenerator(function* () {
|
|
yield _this3.yieldLoop();
|
|
parser.overwrite(options, options, _this3.storeOptions);
|
|
|
|
_this3._startHeartbeat();
|
|
|
|
_this3.instance._drainAll(_this3.computeCapacity());
|
|
|
|
return true;
|
|
})();
|
|
}
|
|
|
|
__running__() {
|
|
var _this4 = this;
|
|
|
|
return _asyncToGenerator(function* () {
|
|
yield _this4.yieldLoop();
|
|
return _this4._running;
|
|
})();
|
|
}
|
|
|
|
__queued__() {
|
|
var _this5 = this;
|
|
|
|
return _asyncToGenerator(function* () {
|
|
yield _this5.yieldLoop();
|
|
return _this5.instance.queued();
|
|
})();
|
|
}
|
|
|
|
__done__() {
|
|
var _this6 = this;
|
|
|
|
return _asyncToGenerator(function* () {
|
|
yield _this6.yieldLoop();
|
|
return _this6._done;
|
|
})();
|
|
}
|
|
|
|
__groupCheck__(time) {
|
|
var _this7 = this;
|
|
|
|
return _asyncToGenerator(function* () {
|
|
yield _this7.yieldLoop();
|
|
return _this7._nextRequest + _this7.timeout < time;
|
|
})();
|
|
}
|
|
|
|
computeCapacity() {
|
|
var maxConcurrent, reservoir;
|
|
var _this$storeOptions2 = this.storeOptions;
|
|
maxConcurrent = _this$storeOptions2.maxConcurrent;
|
|
reservoir = _this$storeOptions2.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;
|
|
}
|
|
}
|
|
|
|
conditionsCheck(weight) {
|
|
var capacity;
|
|
capacity = this.computeCapacity();
|
|
return capacity == null || weight <= capacity;
|
|
}
|
|
|
|
__incrementReservoir__(incr) {
|
|
var _this8 = this;
|
|
|
|
return _asyncToGenerator(function* () {
|
|
var reservoir;
|
|
yield _this8.yieldLoop();
|
|
reservoir = _this8.storeOptions.reservoir += incr;
|
|
|
|
_this8.instance._drainAll(_this8.computeCapacity());
|
|
|
|
return reservoir;
|
|
})();
|
|
}
|
|
|
|
__currentReservoir__() {
|
|
var _this9 = this;
|
|
|
|
return _asyncToGenerator(function* () {
|
|
yield _this9.yieldLoop();
|
|
return _this9.storeOptions.reservoir;
|
|
})();
|
|
}
|
|
|
|
isBlocked(now) {
|
|
return this._unblockTime >= now;
|
|
}
|
|
|
|
check(weight, now) {
|
|
return this.conditionsCheck(weight) && this._nextRequest - now <= 0;
|
|
}
|
|
|
|
__check__(weight) {
|
|
var _this10 = this;
|
|
|
|
return _asyncToGenerator(function* () {
|
|
var now;
|
|
yield _this10.yieldLoop();
|
|
now = Date.now();
|
|
return _this10.check(weight, now);
|
|
})();
|
|
}
|
|
|
|
__register__(index, weight, expiration) {
|
|
var _this11 = this;
|
|
|
|
return _asyncToGenerator(function* () {
|
|
var now, wait;
|
|
yield _this11.yieldLoop();
|
|
now = Date.now();
|
|
|
|
if (_this11.conditionsCheck(weight)) {
|
|
_this11._running += weight;
|
|
|
|
if (_this11.storeOptions.reservoir != null) {
|
|
_this11.storeOptions.reservoir -= weight;
|
|
}
|
|
|
|
wait = Math.max(_this11._nextRequest - now, 0);
|
|
_this11._nextRequest = now + wait + _this11.storeOptions.minTime;
|
|
return {
|
|
success: true,
|
|
wait,
|
|
reservoir: _this11.storeOptions.reservoir
|
|
};
|
|
} else {
|
|
return {
|
|
success: false
|
|
};
|
|
}
|
|
})();
|
|
}
|
|
|
|
strategyIsBlock() {
|
|
return this.storeOptions.strategy === 3;
|
|
}
|
|
|
|
__submit__(queueLength, weight) {
|
|
var _this12 = this;
|
|
|
|
return _asyncToGenerator(function* () {
|
|
var blocked, now, reachedHWM;
|
|
yield _this12.yieldLoop();
|
|
|
|
if (_this12.storeOptions.maxConcurrent != null && weight > _this12.storeOptions.maxConcurrent) {
|
|
throw new BottleneckError(`Impossible to add a job having a weight of ${weight} to a limiter having a maxConcurrent setting of ${_this12.storeOptions.maxConcurrent}`);
|
|
}
|
|
|
|
now = Date.now();
|
|
reachedHWM = _this12.storeOptions.highWater != null && queueLength === _this12.storeOptions.highWater && !_this12.check(weight, now);
|
|
blocked = _this12.strategyIsBlock() && (reachedHWM || _this12.isBlocked(now));
|
|
|
|
if (blocked) {
|
|
_this12._unblockTime = now + _this12.computePenalty();
|
|
_this12._nextRequest = _this12._unblockTime + _this12.storeOptions.minTime;
|
|
|
|
_this12.instance._dropAllQueued();
|
|
}
|
|
|
|
return {
|
|
reachedHWM,
|
|
blocked,
|
|
strategy: _this12.storeOptions.strategy
|
|
};
|
|
})();
|
|
}
|
|
|
|
__free__(index, weight) {
|
|
var _this13 = this;
|
|
|
|
return _asyncToGenerator(function* () {
|
|
yield _this13.yieldLoop();
|
|
_this13._running -= weight;
|
|
_this13._done += weight;
|
|
|
|
_this13.instance._drainAll(_this13.computeCapacity());
|
|
|
|
return {
|
|
running: _this13._running
|
|
};
|
|
})();
|
|
}
|
|
|
|
};
|
|
module.exports = LocalDatastore; |