@jbagatta/johnny-locke
Version:
A robust, strongly-consistent distributed locking library that provides atomic operations across multiple processes
60 lines • 2.36 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.LockListener = void 0;
const util_1 = require("../util");
const data_model_1 = require("./data-model");
class LockListener {
constructor(redis, namespace) {
this.redis = redis;
this.namespace = namespace;
this.listeners = new Map();
this.subscriber = this.redis.duplicate();
this.subscriber.subscribe((0, data_model_1.redisPubSubChannel)(this.namespace));
this.subscriber.on('message', (channel, message) => {
try {
const { key, payload } = JSON.parse(message);
const listeners = this.listeners.get(key);
if (listeners) {
listeners.forEach(callback => callback(payload));
listeners.clear();
}
}
catch (error) {
console.error(error);
}
});
}
async notify(namespacedKey, payload) {
await this.redis.publish((0, data_model_1.redisPubSubChannel)(this.namespace), JSON.stringify({ key: namespacedKey, payload }));
}
async waitUntilNotified(namespacedKey, timeoutMs) {
return new Promise((resolve, reject) => {
this.resolveOnNotification.bind(this)(namespacedKey, timeoutMs, resolve, reject);
});
}
cancel(wait) {
wait.then().catch(() => { });
}
async resolveOnNotification(namespacedKey, timeoutMs, resolve, reject) {
const watchId = crypto.randomUUID();
const timeout = setTimeout(() => {
this.listeners.get(namespacedKey)?.delete(watchId);
reject(new util_1.TimeoutError(namespacedKey));
}, timeoutMs);
const callback = (payload) => {
this.listeners.get(namespacedKey)?.delete(watchId);
clearTimeout(timeout);
resolve(payload);
};
if (!this.listeners.has(namespacedKey)) {
this.listeners.set(namespacedKey, new Map());
}
this.listeners.get(namespacedKey).set(watchId, callback.bind(this));
}
close() {
this.subscriber.unsubscribe((0, data_model_1.redisPubSubChannel)(this.namespace));
this.subscriber.quit().catch(console.error);
}
}
exports.LockListener = LockListener;
//# sourceMappingURL=lock-listener.js.map