UNPKG

@solid/community-server

Version:

Community Solid Server: an open and modular implementation of the Solid specifications

62 lines 2.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GreedyReadWriteLocker = void 0; const InternalServerError_1 = require("../errors/InternalServerError"); const BaseReadWriteLocker_1 = require("./BaseReadWriteLocker"); /** * A {@link BaseReadWriteLocker} that uses the same locker for the main lock and the count lock, * and uses a {@link KeyValueStorage} for keeping track of the counter. * * Since it is completely dependent on other implementations, * this locker is threadsafe if its inputs are as well. */ class GreedyReadWriteLocker extends BaseReadWriteLocker_1.BaseReadWriteLocker { storage; readSuffix; countSuffix; /** * @param locker - Used for creating read and write locks. * @param storage - Used for storing the amount of active read operations on a resource. * @param readSuffix - Used to generate the identifier for the lock that is applied when updating the counter. * @param countSuffix - Used to generate the identifier that will be used in the storage for storing the counter. */ constructor(locker, storage, readSuffix = 'read', countSuffix = 'count') { super(locker, locker); this.storage = storage; this.readSuffix = readSuffix; this.countSuffix = countSuffix; } getCountLockIdentifier(identifier) { return { path: `${identifier.path}.${this.readSuffix}` }; } /** * This key is used for storing the count of active read operations. */ getCountKey(identifier) { return `${identifier.path}.${this.countSuffix}`; } /** * Updates the count with the given modifier. * Creates the data if it didn't exist yet. * Deletes the data when the count reaches zero. */ async modifyCount(identifier, mod) { const countKey = this.getCountKey(identifier); let number = await this.storage.get(countKey) ?? 0; number += mod; if (number === 0) { // Make sure there is no remaining data once all locks are released await this.storage.delete(countKey); } else if (number > 0) { await this.storage.set(countKey, number); } else { // Failsafe in case something goes wrong with the count storage throw new InternalServerError_1.InternalServerError('Read counter would become negative. Something is wrong with the count storage.'); } return number; } } exports.GreedyReadWriteLocker = GreedyReadWriteLocker; //# sourceMappingURL=GreedyReadWriteLocker.js.map