Skip to content

perf(polling): remove idle polling from live sessions - #2919

Merged
joaosouz4dev merged 1 commit into
wppconnect-team:masterfrom
Omix01:perf/idle-polling
Oct 23, 2026
Merged

joaosouz4dev merged 1 commit into
wppconnect-team:masterfrom
Omix01:perf/idle-polling

Conversation

@Omix01

@Omix01 Omix01 commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Three permanent background timers ran for the whole lifetime of every session and every renderer:

  • Whatsapp polled WPP.conn.isRegistered() once per second via page.evaluate, forever.
  • HostLayer.start() scheduled a 5s checkStart() interval that called needsToScan() and discarded the result (dead code).
  • unregisterServiceWorker injected a 500ms setInterval that only reassigned window.onerror/window.onunhandledrejection.

Replace the 1s poll with wa-js connection events (conn.authenticated, conn.main_ready, conn.logout, conn.require_auth) forwarded through an exposed function; disconnectedMobile is still emitted on the unpaired transition. Drop the dead 5s interval and assign the error handlers once per document. For N sessions this removes N page.evaluate calls per second plus two always-on timers per session/renderer.

Refs #2831 — long-running sessions grow memory/CPU over hours; this removes the always-on timers that keep a session busy while idle.

Changes proposed in this pull request

  • src/api/whatsapp.ts: replace the forever 1s WPP.conn.isRegistered() poll with wa-js connection events forwarded to Node through an exposed onConnectionChange; disconnectedMobile is still emitted (deduped) on the unpaired transition and the initial state is seeded once in afterPageScriptInjected.
  • src/api/layers/host.layer.ts: remove the dead 5s checkStart interval (result was discarded) and its unused method/field; QR detection is unchanged and still driven on demand by WPP.on('conn.auth_code_change') → checkQrCode.
  • src/controllers/browser.ts: assign window.onerror/window.onunhandledrejection once per document instead of on a 500ms interval.
  • src/tests/07.idle-polling.test.ts: add 4 regression tests — no periodic evaluate; disconnectedMobile emitted once; start() schedules no 5s poll; injected document script contains no setInterval.
  • .github/workflows/build.yml: run the new spec in CI.

To test (it takes a while): npm install github:Omix01/wppconnect#perf/idle-polling

@Omix01
Omix01 force-pushed the perf/idle-polling branch from 1374cc2 to f5c3f6d Compare October 16, 2026 10:53
@joaosouz4dev

Copy link
Copy Markdown
Member

Thank you for removing the idle polling and adding tests. I am keeping this open for the reused-page event bridge at f5c3f6d.

wireConnectionEvents swallows the duplicate exposeFunction error, leaving the previous client's onConnectionChange callback installed. The existing callback also carries __wppWired, so the second client does not replace the listeners. Running the actual method for two successive clients on one page and emitting conn.logout updates the first client to disconnected, leaves the second client connected, and reports disconnectedMobile for the first session only.

Please replace or redirect the existing binding to the current client and add a two-client reused-page regression. The five Host callbacks covered by #2924 do not include this newly introduced callback.

@Omix01
Omix01 force-pushed the perf/idle-polling branch 2 times, most recently from 75fff42 to a42441d Compare October 16, 2026 18:01
@Omix01

Omix01 commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @joaosouz4dev — fixed at a42441d.

The binding is now replaced, not swallowed. wireConnectionEvents keeps a module-level reference to the current handler. On a reused page it no longer bails out on the duplicate exposeFunction error: it swaps the stored handler to the current client first, so the existing binding routes to the new client instead of the previous one. The __wppWired guard no longer short-circuits that swap.

Two-client reused-page regression added. Runs wireConnectionEvents twice on the same page with two clients, emits conn.logout, and asserts: first client → disconnected, second client stays connected, disconnectedMobile reported for the first session only. The case fails on f5c3f6d and passes now.

Also noted on #2924 — the callback is now in the Host-callback set, so it's covered alongside the other five. Checks are green on a42441d.

@joaosouz4dev

Copy link
Copy Markdown
Member

Thank you, @Omix01, for the per-page dispatcher and reused-page regression. At a42441d the previous-client callback concern is resolved. Before merging the event-based watcher, please preserve the real-unpair guard from #2931 in the new onConnectionChange method. It currently assigns connected=false and emits disconnectedMobile whenever isRegistered is false, including an initial null-to-false transition. Replacing the interval with this method would discard that fix. Please cover never-paired false, true-to-false, and the current-client reused-page dispatch together.

Replace the permanent 1s WPP.conn.isRegistered() poll with wa-js connection events forwarded through an exposed onConnectionChange. Keep the real-unpair guard: only a registered -> unregistered transition emits disconnectedMobile, so a never-paired page that starts at false does not report a disconnect. A reused page redirects its existing binding to the newest client.

Drop the dead 5s checkStart interval and its unused method/field. Assign the in-page error handlers once per document instead of on a 500ms interval.
@Omix01
Omix01 force-pushed the perf/idle-polling branch from a42441d to faab352 Compare October 22, 2026 16:16
@Omix01

Omix01 commented Oct 22, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @joaosouz4dev — fixed at faab352.

I rebased onto master at 111633b6d (so #2931 is in the base and the
whatsapp.ts conflict is gone) and preserved its guard in the new event path:
onConnectionChange records wasConnected before assigning and emits
disconnectedMobile only on true -> false. An initial null -> false
(never paired) updates state but does not log or emit. The initial seed in
afterPageScriptInjected also leaves an event that arrived during the read
intact.

Coverage now includes all three cases:

  • never-paired false -> no status (00 + 07)
  • registered true -> false -> exactly one disconnectedMobile (00 + 07)
  • reused page with two clients -> conn.logout routes to the newest client
    only; the previous client stays connected; a never-paired newest client does
    not emit (07)

I also updated the #2931 watcher tests in 00 to drive onConnectionChange
instead of the removed interval. All checks are green on faab352.

@joaosouz4dev
joaosouz4dev merged commit de07dab into wppconnect-team:master Oct 23, 2026
5 checks passed
@joaosouz4dev

Copy link
Copy Markdown
Member

Merged at de07dab. Thank you, @Omix01, for addressing the review and adding the regression coverage.

The event watcher now preserves the true-to-false unpair guard and does not emit a disconnect for a never-paired false state. Reused-page events are routed to the current client, and a stale initial read cannot overwrite a newer event. I withdrew the previous blocker. The combined changes passed 90 lifecycle/regression tests, types, lint and build; six independent bridge checks exercised the actual injected event registration and dispatch logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants