Skip to content

Bug: Tracking external-feed polling has no in-flight cancel, no per-fetch timeout, and setState fires on unmounted component #42

Description

@kevinelliott

Summary

pollExternalFeeds in client/src/pages/Tracking.tsx (lines 221–304) runs on a setInterval(..., 2000) and does sequential fetches across all enabled feeds. There is no AbortController, no per-fetch timeout, and no "component still mounted" guard.

Impact

Two concrete failure modes:

  1. Overlapping in-flight requests. If one feed URL (or the third-party proxy from Bug: Tracking page external feed loader uses a hard-coded third-party CORS proxy and reads unvalidated localStorage JSON #24) hangs beyond 2 seconds, the next setInterval tick starts a fresh sweep on top of the previous one. Requests accumulate faster than they resolve; the manager and/or the third-party proxy see a slowly growing pileup.

  2. setState on unmounted component. After the user navigates away from the Tracking page, the interval is cleared, but any in-flight fetches keep running. When they resolve they call setExternalVehicles on a dead component (React logs a warning; over time this leaks memory too).

Suggested fix

  • Wrap each fetch with AbortController + a per-request timeout (e.g. 5s).
  • Store the current sweep's controllers in a ref so the effect cleanup can .abort() them.
  • Track an alive ref set to true on mount, false on unmount, and short-circuit setExternalVehicles when !alive.current.

Related but distinct from #24 (which is about the third-party CORS proxy and unvalidated localStorage JSON) — this one is specifically about the polling mechanics.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions