You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

287 lines
8.2 KiB

"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;