UNPKG

@freemework/common

Version:

Common library of the Freemework Project.

102 lines 3.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FLimitInternalTimeSpanLimit = void 0; const f_limit_exception_js_1 = require("../f_limit_exception.js"); const f_internal_limit_sync_base_js_1 = require("./f_internal_limit_sync_base.js"); const f_internal_limit_token_deferred_js_1 = require("./f_internal_limit_token_deferred.js"); class FLimitInternalTimeSpanLimit extends f_internal_limit_sync_base_js_1.FInternalLimitSyncBase { _maxTokens; _activeTokenDefers; _delay; _clearTimeoutFunc; _setTimeoutFunc; _timers = []; constructor(delay, hitCount, stubs = { clearTimeoutFunc: (...args) => clearTimeout(...args), setTimeoutFunc: (...args) => setTimeout(...args) }) { super(); this._maxTokens = hitCount; this._delay = delay; this._clearTimeoutFunc = stubs.clearTimeoutFunc; this._setTimeoutFunc = stubs.setTimeoutFunc; this._activeTokenDefers = []; } get availableWeight() { if (super.disposed) { throw new Error("Wrong operation on disposed object"); } return this._maxTokens - this._activeTokenDefers.reduce((p, c) => p + c.weight, 0); } get maxWeight() { if (super.disposed) { throw new Error("Wrong operation on disposed object"); } return this._maxTokens; } accrueToken(weight) { super.verifyNotDisposed(); if (this.availableWeight < weight) { throw new f_limit_exception_js_1.FLimitException("No any available tokens"); } let defer = null; { // local scope const realDefer = { ...f_internal_limit_token_deferred_js_1.FInternalLimitTokenDeferred.create(weight), finalize: () => { realDefer.resolve(); const index = this._activeTokenDefers.indexOf(realDefer); this._activeTokenDefers.splice(index, 1); this.raiseReleaseToken(); }, finalizing: false }; this._activeTokenDefers.push(realDefer); defer = realDefer; } const token = { commit: () => { if (defer !== null) { const selfDefer = defer; defer = null; selfDefer.finalizing = true; if (!super.disposing) { const timer = this._setTimeoutFunc(() => { const timerIndex = this._timers.indexOf(timer); if (timerIndex !== -1) { this._timers.splice(timerIndex, 1); } selfDefer.finalize(); }, this._delay); this._timers.push(timer); } else { selfDefer.finalize(); } } }, rollback: () => { if (defer !== null) { const selfDefer = defer; defer = null; selfDefer.finalizing = true; selfDefer.finalize(); } } }; return token; } async onDispose() { this._timers.slice().forEach(timer => { this._clearTimeoutFunc(timer); const timerIndex = this._timers.indexOf(timer); if (timerIndex !== -1) { this._timers.splice(timerIndex, 1); } }); this._activeTokenDefers.filter(w => w.finalizing).forEach(d => d.finalize()); await Promise.all(this._activeTokenDefers.map(d => d.promise)); } } exports.FLimitInternalTimeSpanLimit = FLimitInternalTimeSpanLimit; //# sourceMappingURL=f_limit_internal_time_span_limit.js.map