Skip to content

Add TTL-based eviction for orphaned initialHostByRequest entries#46

Merged
ormidales merged 3 commits into1.0.2from
copilot/fix-orphan-requests-cleanup
Feb 16, 2026
Merged

Add TTL-based eviction for orphaned initialHostByRequest entries#46
ormidales merged 3 commits into1.0.2from
copilot/fix-orphan-requests-cleanup

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 16, 2026

initialHostByRequest was only cleaned on terminal webRequest events (onCompleted, onErrorOccurred, block path in onHeadersReceived). When requests are canceled upstream (e.g. by another extension), those events are not guaranteed, leaving stale entries in the tracking map.

  • Problem scope

    • Prevent dead request IDs from accumulating when final lifecycle events do not fire.
    • Preserve existing redirect decision behavior while tightening lifecycle hygiene.
  • Tracking model update

    • Store tracked requests as { host, trackedAt } instead of raw host strings.
    • Keep redirect host resolution compatible with current map contents by reading trackedRequest.host and falling back safely.
  • TTL eviction for orphaned requests

    • Added REQUEST_TRACK_TTL_MS and a periodic sweeper (setInterval) that removes entries older than the TTL.
    • Existing cleanup paths (onCompleted, onErrorOccurred, redirect/block handling) remain unchanged and continue to remove entries eagerly.
const REQUEST_TRACK_TTL_MS = 60 * 1000;

initialHostByRequest.set(requestId, { host, trackedAt: Date.now() });

const cleanupStaleTrackedRequests = (now = Date.now()) => {
  for (const [requestId, trackedRequest] of initialHostByRequest.entries()) {
    if (trackedRequest && typeof trackedRequest === "object" &&
        now - trackedRequest.trackedAt > REQUEST_TRACK_TTL_MS) {
      initialHostByRequest.delete(requestId);
    }
  }
};

setInterval(cleanupStaleTrackedRequests, REQUEST_TRACK_TTL_MS);
Original prompt

This section details on the original issue you should resolve

<issue_title>Nettoyage incomplet des requêtes orphelines dans la Map de suivi</issue_title>
<issue_description>## Contexte
L'extension maintient une structure initialHostByRequest pour lier les identifiants de requête réseau à leur hôte initial.

Problème

Les requêtes sont supprimées sur onCompleted, onErrorOccurred ou lors du blocage dans onHeadersReceived. Cependant, des flux de requêtes réseau bloqués par d'autres extensions (ex: bloqueurs de publicités) peuvent ne déclencher aucun de ces événements finaux de manière garantie, laissant des entrées mortes.

Scénario de Reproduction

  1. Installer une extension de blocage agressive à côté de TruePath.
  2. Naviguer intensivement.
  3. Surveiller la taille de initialHostByRequest.

Comportement Attendu

La Map ne doit contenir que les requêtes réellement en cours d'évaluation.

Pistes Techniques

Bien que le système rotatif (MAX_TRACKED_REQUESTS) évite les fuites mémoire majeures, il serait pertinent d'ajouter un écouteur sur onCanceled (si disponible selon la version de l'API webRequest) ou d'implémenter un TTL (Time To Live) par entrée.

Environnement

Toutes plateformes.</issue_description>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits February 16, 2026 20:36
Co-authored-by: ormidales <46538211+ormidales@users.noreply.github.com>
Co-authored-by: ormidales <46538211+ormidales@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix incomplete cleanup of orphaned requests in tracking map Add TTL-based eviction for orphaned initialHostByRequest entries Feb 16, 2026
Copilot AI requested a review from ormidales February 16, 2026 20:38
@ormidales ormidales added this to the v1.0.2 milestone Feb 16, 2026
@ormidales ormidales linked an issue Feb 16, 2026 that may be closed by this pull request
@ormidales ormidales marked this pull request as ready for review February 16, 2026 20:43
Copilot AI review requested due to automatic review settings February 16, 2026 20:43
@ormidales ormidales merged commit b79d1bf into 1.0.2 Feb 16, 2026
@ormidales ormidales deleted the copilot/fix-orphan-requests-cleanup branch February 16, 2026 20:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses orphaned entries in the initialHostByRequest tracking map that accumulate when webRequest lifecycle events don't fire (e.g., when requests are canceled by other extensions). The solution introduces a TTL-based cleanup mechanism alongside existing eager deletion paths.

Changes:

  • Migrated initialHostByRequest from storing raw hostname strings to structured objects containing { host, trackedAt }
  • Added periodic TTL-based sweeper (60-second interval) to remove entries older than REQUEST_TRACK_TTL_MS
  • Updated retrieval logic in onHeadersReceived with backward compatibility for both object and legacy string formats

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread background.js
}
};

setInterval(cleanupStaleTrackedRequests, REQUEST_TRACK_TTL_MS);
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setInterval timer created here will run indefinitely without a cleanup mechanism. While this is acceptable for a background script that lives for the extension's lifetime, consider storing the interval ID if you need to clear it during extension unload or testing: const cleanupIntervalId = setInterval(cleanupStaleTrackedRequests, REQUEST_TRACK_TTL_MS);

Suggested change
setInterval(cleanupStaleTrackedRequests, REQUEST_TRACK_TTL_MS);
const cleanupIntervalId = setInterval(cleanupStaleTrackedRequests, REQUEST_TRACK_TTL_MS);

Copilot uses AI. Check for mistakes.
Comment thread background.js
@@ -1,5 +1,6 @@
const initialHostByRequest = new Map();
const MAX_TRACKED_REQUESTS = 1000;
const REQUEST_TRACK_TTL_MS = 60 * 1000;
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 60-second TTL may be too short for slow network conditions or complex redirect chains. Consider increasing to 2-5 minutes (120000-300000 ms) to reduce the risk of prematurely evicting legitimate long-running requests while still preventing indefinite accumulation.

Suggested change
const REQUEST_TRACK_TTL_MS = 60 * 1000;
const REQUEST_TRACK_TTL_MS = 5 * 60 * 1000;

Copilot uses AI. Check for mistakes.
Comment thread background.js

const cleanupStaleTrackedRequests = (now = Date.now()) => {
for (const [requestId, trackedRequest] of initialHostByRequest.entries()) {
if (trackedRequest && typeof trackedRequest === "object" && now - trackedRequest.trackedAt > REQUEST_TRACK_TTL_MS) {
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition relies on NaN > REQUEST_TRACK_TTL_MS being false when trackedAt is missing. Consider adding an explicit check for trackedAt to make the logic clearer: if (trackedRequest && typeof trackedRequest === "object" && typeof trackedRequest.trackedAt === "number" && now - trackedRequest.trackedAt > REQUEST_TRACK_TTL_MS)

Suggested change
if (trackedRequest && typeof trackedRequest === "object" && now - trackedRequest.trackedAt > REQUEST_TRACK_TTL_MS) {
if (
trackedRequest &&
typeof trackedRequest === "object" &&
typeof trackedRequest.trackedAt === "number" &&
now - trackedRequest.trackedAt > REQUEST_TRACK_TTL_MS
) {

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Nettoyage incomplet des requêtes orphelines dans la Map de suivi

3 participants