Skip to content

Comments

fix: memory leak and performance in Last Calls section#92

Open
edospadoni wants to merge 1 commit intomainfrom
fix/last-calls-memory-leak-performance
Open

fix: memory leak and performance in Last Calls section#92
edospadoni wants to merge 1 commit intomainfrom
fix/last-calls-memory-leak-performance

Conversation

@edospadoni
Copy link
Member

Problem

A customer with high call volume (~1300 calls/day, 1.8M CDR records) experiences white screen and slowdowns when NethLink stays open on the "Last calls" tab for extended periods.

Root cause analysis identified four issues:

  1. Unbounded missedCalls array — Grows indefinitely over time without ever being truncated, consuming increasing amounts of memory
  2. O(n²) operations during renderingprepareCalls() runs missedCalls.map().includes() for every call, and gestLastCalls() uses lodash differenceWith with linear comparisons
  3. IPC event listeners without cleanup — 8 listeners registered in NethLinkPage and 1 in the store are never removed, accumulating on every mount/unmount cycle
  4. Full array spreads on every update — A complete copy of the entire calls array is created on every update

Changes

usePhoneIslandEventHandler.tsgestLastCalls()

  • Replaced lodash differenceWith with Set for O(1) uniqueid lookups
  • Removed lodash import (no longer needed)
  • Capped missedCalls at 50 elements (oldest entries are dropped)
  • Used Set for deduplication in setMissedCalls instead of array.map().includes()
  • Removed unnecessary spread of newLastCalls.rows

LastCallsBox.tsxprepareCalls()

  • Pre-computed missedCallIds as a Set once before the .map() loop
  • Replaced missedCalls?.map(c => c.uniqueid).includes(c.uniqueid) (O(n) per call = O(n²) total) with missedCallIds.has(c.uniqueid) (O(1) per call = O(n) total)

NethLinkPage.tsx — IPC listener cleanup

  • Moved 8 IPC listener registrations from useInitialize (no cleanup) into the useEffect watching account?.username
  • Added cleanup function calling removeAllListeners for all channels
  • Kept notification permission request in useInitialize (one-time, no cleanup needed)

store.ts — store listener cleanup

  • Added cleanup function in useRegisterStoreHook's useEffect to remove the SHARED_STATE_UPDATED listener and reset isRegistered

- Limit missedCalls array to 50 elements to prevent unbounded growth
- Replace lodash differenceWith and array.map().includes() with Set
  lookups for O(1) uniqueid comparison
- Add cleanup for IPC event listeners in NethLinkPage and store
- Remove unnecessary array spreads on every update
@github-actions
Copy link

Automatic builds from https://github.com/NethServer/nethlink/actions/runs/22133814277.
Commit: bc7657f

Name Platform Link
win-app.exe Windows (x64) Link
macos-app-x64.dmg MacOS (x64) Link
macos-app-arm64.dmg MacOS (arm64) Link
linux-app.AppImage Linux (x64) Link

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.

1 participant