fix(socket): give init queries headroom + add CB kill-switch env var
Production report: after scanning QR for a brand-new channel the user gets "WhatsApp não inicializado" / "1 sem ativação" because the `socket-query` circuit breaker opens during the post-pairing `init queries` (USync, device-list, app-state-sync). Existing channels are unaffected — only fresh pairings trip the CB because their first round of metadata fetches is slow (no warm server-side cache for the client, larger payload). Two small changes: 1. Bump the `socket-query` CB timeout floor to 120 s (was `defaultQueryTimeoutMs || 60000`, which evaluated to 30 s in this build). The per-query `waitForMessage` timeout still enforces a tighter bound for individual operations — this only widens the *cumulative* window the CB watches before tripping. 2. Add `BAILEYS_DISABLE_CIRCUIT_BREAKER=true` env var as an emergency kill-switch so operators can disable all three CBs (query, connection, prekey) without touching code or rebuilding zpro. The default `enableCircuitBreaker` config flag still works for callers that pass it in code. No behavior change for existing channels under normal load — the bump only matters when init queries actually take longer than 30 s. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+15
-4
@@ -107,20 +107,31 @@ export const makeSocket = (config: SocketConfig) => {
|
|||||||
const enableUnifiedSession =
|
const enableUnifiedSession =
|
||||||
enableUnifiedSessionConfig !== undefined ? enableUnifiedSessionConfig : shouldEnableUnifiedSession()
|
enableUnifiedSessionConfig !== undefined ? enableUnifiedSessionConfig : shouldEnableUnifiedSession()
|
||||||
|
|
||||||
// Initialize circuit breakers if enabled
|
// Initialize circuit breakers if enabled.
|
||||||
|
//
|
||||||
|
// Env var override: BAILEYS_DISABLE_CIRCUIT_BREAKER=true completely disables
|
||||||
|
// all three circuit breakers without requiring a code change. Useful when the
|
||||||
|
// query CB is opening on slow `init queries` after a fresh QR pairing — those
|
||||||
|
// initial USync / device-list / app-state queries can legitimately take longer
|
||||||
|
// than the per-call timeout when the auth state is fresh and the server has
|
||||||
|
// no warm caches for this client.
|
||||||
|
const envDisableCB = process.env.BAILEYS_DISABLE_CIRCUIT_BREAKER === 'true'
|
||||||
let queryCircuitBreaker: CircuitBreaker | undefined
|
let queryCircuitBreaker: CircuitBreaker | undefined
|
||||||
let connectionCircuitBreaker: CircuitBreaker | undefined
|
let connectionCircuitBreaker: CircuitBreaker | undefined
|
||||||
let preKeyCircuitBreaker: CircuitBreaker | undefined
|
let preKeyCircuitBreaker: CircuitBreaker | undefined
|
||||||
|
|
||||||
if (enableCircuitBreaker) {
|
if (enableCircuitBreaker && !envDisableCB) {
|
||||||
// Circuit breaker for query operations (most critical)
|
// Circuit breaker for query operations (most critical).
|
||||||
|
// timeout=120s gives `init queries` (USync, device-list, app-state-sync)
|
||||||
|
// enough room on fresh QR pairings; the per-query timeout in waitForMessage
|
||||||
|
// already enforces a tighter bound for individual operations.
|
||||||
queryCircuitBreaker = createConnectionCircuitBreaker({
|
queryCircuitBreaker = createConnectionCircuitBreaker({
|
||||||
name: 'socket-query',
|
name: 'socket-query',
|
||||||
failureThreshold: 5,
|
failureThreshold: 5,
|
||||||
failureWindow: 60000,
|
failureWindow: 60000,
|
||||||
resetTimeout: 30000,
|
resetTimeout: 30000,
|
||||||
successThreshold: 2,
|
successThreshold: 2,
|
||||||
timeout: defaultQueryTimeoutMs || 60000,
|
timeout: Math.max(defaultQueryTimeoutMs || 0, 120_000),
|
||||||
onStateChange: (from, to) => {
|
onStateChange: (from, to) => {
|
||||||
logger.info({ from, to }, 'Query circuit breaker state changed')
|
logger.info({ from, to }, 'Query circuit breaker state changed')
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user