UNPKG

@newdash/newdash

Version:

javascript/typescript utility library

79 lines (78 loc) 2.65 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SemaphoreMap = void 0; const LRUMap_1 = require("./LRUMap"); const Semaphore_1 = __importDefault(require("./Semaphore")); const toHashCode_1 = __importDefault(require("./toHashCode")); const KEY_DEFAULT = "default"; const DEFAULT_EXTRACTOR = (args) => args; /** * high level SemaphoreMap * * @since 5.18.0 * @category Functional */ class SemaphoreMap { _container; _defaultSemCount; /** * SemaphoreMap, provision semaphore with giving key * * @param maximumSemObjects maximumSemObjects to avoid OOM, the default value is 1000000 * @param defaultSemCount default sem permit number, the default value is 10 */ constructor(maximumSemObjects = 1000 * 1000, defaultSemCount = 10) { this._container = new LRUMap_1.LRUMap(maximumSemObjects); this._defaultSemCount = defaultSemCount; } /** * get semaphore or create a new one * * @param semaphoreKey * @param count */ getOrCreate(semaphoreKey = KEY_DEFAULT, count) { const hashKey = (0, toHashCode_1.default)(semaphoreKey); if (!this._container.has(hashKey)) { this._container.set(hashKey, new Semaphore_1.default(count ?? this._defaultSemCount)); } return this._container.get(hashKey); } /** * execute function with specify semaphore instance * * @param key the key of semaphore * @param runner async runner */ execute(key = KEY_DEFAULT, runner) { return this.getOrCreate(key).use(runner); } /** * wrap a function with semaphore, the different parameter will use different semaphore instance * * simply, it could be used as a deeply 'limit' function, * after wrapping, * the function will be limited by parameter values (by specific semaphore total count) * * @param runner * @param runner params extractor, the return value will be used to determine the semaphore */ wrap(runner, extractor = DEFAULT_EXTRACTOR) { return (...args) => this.execute(extractor(args), runner); } /** * static 'wrap' creator for function * @param maxSemNum * @param defaultSemCount * @param runner * @returns */ static wrap(maxSemNum, defaultSemCount, runner) { return (new SemaphoreMap(maxSemNum, defaultSemCount)).wrap(runner); } } exports.SemaphoreMap = SemaphoreMap; exports.default = SemaphoreMap;