Skip to content

Add SequentialQueue pause watchdog to self-heal orphaned pauses #97331

Description

@mountiny

Problem

When the client detects an Onyx-update gap, the SequentialQueue is paused (via shouldPauseQueue in the SaveResponseInOnyx middleware, or SequentialQueue.pause() in applyOnyxUpdatesReliably/DeferredOnyxUpdates) and is only unpaused once the OnyxUpdateManager finishes resolving the gap. That pause/unpause pair is not balanced by construction — several early-return and failure paths in the async chain (non-leader tab early return in handleMissingOnyxUpdates, a subscription that never re-fires, a dead in-progress fetch promise) leave the queue paused forever. Queued write commands like OpenApp then never execute, IS_LOADING_APP never clears, and the user is stuck on a full-screen skeleton on every page until a hard page refresh; reads park forever on waitForIdle(). This was reproduced deterministically by switching priority mode from #focus to normal, which left OpenApp and PusherPing stuck with [SequentialQueue] Unable to flush. Queue is paused. repeating indefinitely, and it matches user reports of intermittent "infinite skeleton" sessions lasting 10+ minutes that only resolve by resetting client state.

Solution

Add a pause watchdog inside SequentialQueue, which owns isQueuePaused. pause() arms a timeout (CONST.NETWORK.MAX_PAUSE_WATCHDOG_TIME_MS, 60s) and unpause()/resetQueue() clear it. A connectWithoutView subscription to ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT re-arms the watchdog on every applied-update advance while paused, so a genuinely progressing (even slow) catch-up never trips it — only a pause with zero progress for the full window does. When it fires, it emits a Log.alert so residual root causes stay visible in telemetry, then force-calls unpause(), which flushes the queue and re-runs the stuck OpenApp/ReconnectApp to re-sync the client and clear the skeleton. This is a liveness safety net rather than a root-cause fix for each individual orphaning path: it converts every "stuck forever until refresh" variant into a bounded ≤60s stall that self-heals.

PR

#97228

Issue OwnerCurrent Issue Owner: @abzokhattab

Metadata

Metadata

Labels

Type

No type

Projects

Status
CRITICAL

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions