Skip to content

fix: prevent duplicate cleanup intervals on background script reload#89

Merged
ormidales merged 3 commits into1.0.5from
copilot/fix-cleanup-interval-memory-issue
Mar 7, 2026
Merged

fix: prevent duplicate cleanup intervals on background script reload#89
ormidales merged 3 commits into1.0.5from
copilot/fix-cleanup-interval-memory-issue

Conversation

Copy link
Contributor

Copilot AI commented Mar 6, 2026

Each time the background script reloads without a full context reset, a new setInterval loop was spawned without clearing the previous one — silently multiplying cleanup executions and leaking memory/CPU over time.

Change

  • Guard the setInterval registration in background.js by storing its ID on globalThis under a namespaced key and clearing any prior interval before creating a new one:
const CLEANUP_INTERVAL_KEY = "__acceptLangExt_cleanupIntervalId";
const existingCleanupIntervalId = globalThis[CLEANUP_INTERVAL_KEY];
if (typeof existingCleanupIntervalId === "number" || typeof existingCleanupIntervalId === "object") {
  clearInterval(existingCleanupIntervalId);
}
globalThis[CLEANUP_INTERVAL_KEY] = setInterval(cleanupStaleTrackedRequests, REQUEST_TRACK_TTL_MS);
  • The key is namespaced (__acceptLangExt_cleanupIntervalId) to avoid collisions with other scripts or future dependencies.
  • A typeof type guard (number or object) ensures only our own interval is ever cleared, protecting against accidental interference with unrelated globals.

globalThis persists across script re-executions within the same global context, ensuring exactly one cleanup loop is active regardless of how many times the script reloads.

Original prompt

This section details on the original issue you should resolve

<issue_title>Nettoyer l'intervalle de purge des requêtes orphelines</issue_title>
<issue_description>## Contexte
L'extension maintient un suivi des requêtes initiales via une Map en mémoire, et exécute une fonction cleanupStaleTrackedRequests régulièrement.

Problème

La fonction setInterval est appelée au niveau global de background.js sans conserver son identifiant. Bien que cela fonctionne dans un environnement persistant, les cycles de vie modernes d'extensions (suspend/resume) peuvent amener le script à se recharger partiellement, multipliant silencieusement les boucles d'intervalle et provoquant une fuite de mémoire.

Scénario de Reproduction

  1. Recharger le script d'arrière-plan plusieurs fois d'affilée sans réinitialiser le contexte global.
  2. Monitorer les performances du worker.
  3. Constater l'exécution multiple et superflue de la fonction de nettoyage chaque minute.

Comportement Attendu

Il ne doit y avoir qu'une seule instance de la boucle de nettoyage en cours d'exécution.

Pistes Techniques

Fichier background.js :
Conserver la référence de l'intervalle et la nettoyer avant de la recréer, ou lier le nettoyage aux événements de cycle de vie de l'extension.

if (globalThis.cleanupIntervalId) {
  clearInterval(globalThis.cleanupIntervalId);
}
globalThis.cleanupIntervalId = setInterval(cleanupStaleTrackedRequests, REQUEST_TRACK_TTL_MS);

Environnement

Service Worker / Background Script.</issue_description>

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


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: ormidales <46538211+ormidales@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix cleanup interval for orphaned request tracking fix: prevent duplicate cleanup intervals on background script reload Mar 6, 2026
@ormidales ormidales added this to the v1.0.5 milestone Mar 7, 2026
@ormidales ormidales linked an issue Mar 7, 2026 that may be closed by this pull request
@ormidales ormidales marked this pull request as ready for review March 7, 2026 11:40
Copilot AI review requested due to automatic review settings March 7, 2026 11:40
Copy link
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 aims to prevent multiple concurrent cleanup loops from accumulating by ensuring the periodic cleanupStaleTrackedRequests interval is de-duplicated across background script re-executions.

Changes:

  • Clear any previously registered cleanup interval before creating a new one.
  • Store the interval ID on globalThis to allow reuse across script re-execution within the same global context.

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

background.js Outdated
Comment on lines +129 to +132
if (globalThis.cleanupIntervalId) {
clearInterval(globalThis.cleanupIntervalId);
}
globalThis.cleanupIntervalId = setInterval(cleanupStaleTrackedRequests, REQUEST_TRACK_TTL_MS);
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

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

globalThis.cleanupIntervalId is a very generic global property name; if more background scripts (or future dependencies) add their own interval tracking, this risks collisions and accidentally clearing the wrong interval. Consider namespacing the key (e.g., a project-specific prefix) and/or guarding the clearInterval call with a type check (number/object) to ensure you only clear your own interval.

Suggested change
if (globalThis.cleanupIntervalId) {
clearInterval(globalThis.cleanupIntervalId);
}
globalThis.cleanupIntervalId = setInterval(cleanupStaleTrackedRequests, REQUEST_TRACK_TTL_MS);
const CLEANUP_INTERVAL_KEY = "__acceptLangExt_cleanupIntervalId";
const existingCleanupIntervalId = globalThis[CLEANUP_INTERVAL_KEY];
if (typeof existingCleanupIntervalId === "number" || typeof existingCleanupIntervalId === "object") {
clearInterval(existingCleanupIntervalId);
}
globalThis[CLEANUP_INTERVAL_KEY] = setInterval(cleanupStaleTrackedRequests, REQUEST_TRACK_TTL_MS);

Copilot uses AI. Check for mistakes.
background.js Outdated
Comment on lines +129 to +132
if (globalThis.cleanupIntervalId) {
clearInterval(globalThis.cleanupIntervalId);
}
globalThis.cleanupIntervalId = setInterval(cleanupStaleTrackedRequests, REQUEST_TRACK_TTL_MS);
Copy link

Copilot AI Mar 7, 2026

Choose a reason for hiding this comment

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

PR description references a MV3 Service Worker lifecycle, but this repo’s manifest.json is manifest_version: 2 with a classic background page (background.scripts). In MV2, background reloads typically destroy the old JS context (and its interval), so this change may not address the reported reproduction scenario; please confirm the issue occurs in the current MV2 runtime or update the PR description/linked issue context accordingly.

Copilot uses AI. Check for mistakes.
@ormidales
Copy link
Owner

@copilot apply changes based on the comments in this thread

…rInterval

Co-authored-by: ormidales <46538211+ormidales@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 7, 2026

@copilot apply changes based on the comments in this thread

Done in 874cebb. The globalThis key is now namespaced to __acceptLangExt_cleanupIntervalId, and a typeof type check (number or object) guards the clearInterval call to ensure only our own interval is ever cleared.

@ormidales ormidales merged commit 4effa09 into 1.0.5 Mar 7, 2026
@ormidales ormidales deleted the copilot/fix-cleanup-interval-memory-issue branch March 7, 2026 11:48
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.

Nettoyer l'intervalle de purge des requêtes orphelines

3 participants