refactor(core): Make setting and expiration of leader key atomic (#14702)

This commit is contained in:
Iván Ovejero
2025-04-17 10:36:37 +02:00
committed by GitHub
parent 77e2ac6495
commit 048df28d5f
2 changed files with 8 additions and 7 deletions

View File

@@ -108,15 +108,17 @@ export class MultiMainSetup extends TypedEmitter<MultiMainEvents> {
const { hostId } = this.instanceSettings; const { hostId } = this.instanceSettings;
// this can only succeed if leadership is currently vacant // this can only succeed if leadership is currently vacant
const keySetSuccessfully = await this.publisher.setIfNotExists(this.leaderKey, hostId); const keySetSuccessfully = await this.publisher.setIfNotExists(
this.leaderKey,
hostId,
this.leaderKeyTtl,
);
if (keySetSuccessfully) { if (keySetSuccessfully) {
this.logger.debug(`[Instance ID ${hostId}] Leader is now this instance`); this.logger.debug(`[Instance ID ${hostId}] Leader is now this instance`);
this.instanceSettings.markAsLeader(); this.instanceSettings.markAsLeader();
await this.publisher.setExpiration(this.leaderKey, this.leaderKeyTtl);
this.emit('leader-takeover'); this.emit('leader-takeover');
} else { } else {
this.instanceSettings.markAsFollower(); this.instanceSettings.markAsFollower();

View File

@@ -86,10 +86,9 @@ export class Publisher {
// @TODO: The following methods are not pubsub-specific. Consider a dedicated client for multi-main setup. // @TODO: The following methods are not pubsub-specific. Consider a dedicated client for multi-main setup.
async setIfNotExists(key: string, value: string) { async setIfNotExists(key: string, value: string, ttl: number) {
const success = await this.client.setnx(key, value); const result = await this.client.set(key, value, 'EX', ttl, 'NX');
return result === 'OK';
return !!success;
} }
async setExpiration(key: string, ttl: number) { async setExpiration(key: string, ttl: number) {