refactor(signal): replace circuit-breaker with bounded-retry in libsignal wrapper

The preKeyCircuitBreaker was passed into signalStorage() as an optional
parameter and was used in only ONE place: .reset() after detecting an
identity-key change (line 391, the 'contact may have reinstalled WhatsApp'
recovery path).

Bounded-retry is stateless — each retry is independent — so the equivalent
of "forget the past failures" happens automatically on the next operation.
There is no state to reset.

Changes:
- Drop CircuitBreaker import.
- Remove preKeyCircuitBreaker field from LibSignalRepositoryOptions.
- Remove preKeyCircuitBreaker parameter from signalStorage().
- Remove the .reset() call in the identity-key-change recovery path
  (replaced with explanatory comment).

Build passes.
This commit is contained in:
Renato Alcara
2026-04-26 22:48:23 -03:00
parent b531b46999
commit a6cf9b0b26
+5 -13
View File
@@ -6,7 +6,6 @@ import type { LIDMapping, SignalAuthState, SignalKeyStoreWithTransaction } from
import type { BaileysEventEmitter } from '../Types/Events' import type { BaileysEventEmitter } from '../Types/Events'
import type { SignalRepositoryWithLIDStore } from '../Types/Signal' import type { SignalRepositoryWithLIDStore } from '../Types/Signal'
import { generateSignalPubKey } from '../Utils' import { generateSignalPubKey } from '../Utils'
import { CircuitBreaker } from '../Utils/circuit-breaker.js'
import type { ILogger } from '../Utils/logger' import type { ILogger } from '../Utils/logger'
import { metrics } from '../Utils/prometheus-metrics.js' import { metrics } from '../Utils/prometheus-metrics.js'
import { isAnyLidUser, isAnyPnUser, jidDecode, transferDevice, WAJIDDomains } from '../WABinary' import { isAnyLidUser, isAnyPnUser, jidDecode, transferDevice, WAJIDDomains } from '../WABinary'
@@ -67,8 +66,6 @@ export interface IdentitySaveResult {
export interface LibSignalRepositoryOptions { export interface LibSignalRepositoryOptions {
/** Event emitter for broadcasting identity changes */ /** Event emitter for broadcasting identity changes */
ev?: BaileysEventEmitter ev?: BaileysEventEmitter
/** Circuit breaker for prekey operations (optional) */
preKeyCircuitBreaker?: CircuitBreaker
} }
// ============================================ // ============================================
@@ -256,7 +253,7 @@ export function makeLibSignalRepository(
pnToLIDFunc?: (jids: string[]) => Promise<LIDMapping[] | undefined>, pnToLIDFunc?: (jids: string[]) => Promise<LIDMapping[] | undefined>,
options?: LibSignalRepositoryOptions options?: LibSignalRepositoryOptions
): SignalRepositoryWithLIDStore { ): SignalRepositoryWithLIDStore {
const { ev, preKeyCircuitBreaker } = options || {} const { ev } = options || {}
const lidMapping = new LIDMappingStore(auth.keys as SignalKeyStoreWithTransaction, logger, pnToLIDFunc) const lidMapping = new LIDMappingStore(auth.keys as SignalKeyStoreWithTransaction, logger, pnToLIDFunc)
// Identity key cache to avoid repeated storage reads // Identity key cache to avoid repeated storage reads
@@ -277,7 +274,7 @@ export function makeLibSignalRepository(
cacheMetricsInterval.unref() cacheMetricsInterval.unref()
} }
const storage = signalStorage(auth, lidMapping, identityKeyCache, ev, preKeyCircuitBreaker, logger) const storage = signalStorage(auth, lidMapping, identityKeyCache, ev, logger)
const parsedKeys = auth.keys as SignalKeyStoreWithTransaction const parsedKeys = auth.keys as SignalKeyStoreWithTransaction
const migratedSessionCache = new LRUCache<string, true>({ const migratedSessionCache = new LRUCache<string, true>({
@@ -385,13 +382,9 @@ export function makeLibSignalRepository(
'Identity key changed - contact may have reinstalled WhatsApp, session will be re-established' 'Identity key changed - contact may have reinstalled WhatsApp, session will be re-established'
) )
// Reset prekey circuit breaker since we identified the cause // (No circuit breaker to reset — bounded-retry is stateless,
// Reset regardless of state (could be open, half-open, or closed with accumulated failures) // each retry is independent so identity-change recovery
// eslint-disable-next-line max-depth // happens automatically on the next operation.)
if (preKeyCircuitBreaker) {
preKeyCircuitBreaker.reset()
logger.debug({ jid }, 'Reset prekey circuit breaker after identity key change detection')
}
} else if (saveResult.isNew) { } else if (saveResult.isNew) {
logger.debug( logger.debug(
{ jid, addr: addrStr, fingerprint: saveResult.currentFingerprint }, { jid, addr: addrStr, fingerprint: saveResult.currentFingerprint },
@@ -769,7 +762,6 @@ function signalStorage(
lidMapping: LIDMappingStore, lidMapping: LIDMappingStore,
identityKeyCache: LRUCache<string, Uint8Array>, identityKeyCache: LRUCache<string, Uint8Array>,
ev?: BaileysEventEmitter, ev?: BaileysEventEmitter,
preKeyCircuitBreaker?: CircuitBreaker,
logger?: ILogger logger?: ILogger
): ExtendedSignalStorage { ): ExtendedSignalStorage {
// Shared function to resolve PN signal address to LID if mapping exists // Shared function to resolve PN signal address to LID if mapping exists