Skip to content

fix: serialize domain deletions with isRemoving flag to prevent race condition#134

Closed
Copilot wants to merge 1 commit into1.0.8from
copilot/fix-race-condition-domains
Closed

fix: serialize domain deletions with isRemoving flag to prevent race condition#134
Copilot wants to merge 1 commit into1.0.8from
copilot/fix-race-condition-domains

Conversation

Copy link
Contributor

Copilot AI commented Mar 11, 2026

Two rapid clicks on distinct "Supprimer" buttons could interleave their async read-modify-write cycles, causing the second getStoredDomains() to read stale data and a deleted domain to reappear after the subsequent renderList().

Changes

  • popup.jsrenderList delete handler:
    • Added module-level let isRemoving = false flag, mirroring the existing isAddingDomain pattern
    • Guard checks if (isRemoving) return and sets isRemoving = true synchronously before any await, ensuring only one deletion runs at a time
    • All list buttons are disabled immediately after the flag is set (buttons.forEach((b) => (b.disabled = true)))
    • try/finally resets the flag and calls await renderList() unconditionally, rebuilding the list from authoritative storage state regardless of success or failure
removeButton.addEventListener("click", async () => {
  if (isRemoving) return;
  isRemoving = true;
  buttons.forEach((b) => (b.disabled = true));
  try {
    // read-modify-write
  } finally {
    isRemoving = false;
    await renderList(); // always re-render from storage
  }
});
Original prompt

This section details on the original issue you should resolve

<issue_title>[MINOR] Race condition sur la suppression simultanée de domaines dans renderList</issue_title>
<issue_description>Catégorie : bug
Sévérité : minor
Fichier(s) concerné(s) : popup.js (l.43–65)

Description

Le bouton "Supprimer" dans renderList effectue deux opérations asynchrones séquentielles : il retire l'élément du DOM immédiatement, puis lit l'état depuis browser.storage.sync avant d'écrire la version filtrée. Si l'utilisateur clique sur deux boutons "Supprimer" très rapidement, le second getStoredDomains() peut lire une liste qui n'a pas encore été mise à jour par le premier set(), entraînant la réapparition du domaine supprimé lors d'un renderList() ultérieur.

Exemple de code problématique

removeButton.addEventListener("click", async () => {
  item.remove(); // DOM modifié immédiatement
  // ...
  const currentDomains = await getStoredDomains(); // lecture stale possible
  const nextDomains = currentDomains.filter((entry) => entry !== domain);
  await browser.storage.sync.set({ [STORAGE_KEY]: nextDomains });
});

Solution suggérée

Désactiver tous les boutons "Supprimer" le temps de l'opération, ou utiliser un verrou (flag isRemoving) similaire à isAddingDomain, pour sérialiser les suppressions.

let isRemoving = false;

removeButton.addEventListener("click", async () => {
  if (isRemoving) return;
  isRemoving = true;
  list.querySelectorAll("li button").forEach(b => b.disabled = true);

  try {
    item.remove();
    // ... gestion focus ...
    const currentDomains = await getStoredDomains();
    const nextDomains = currentDomains.filter((entry) => entry !== domain);
    await browser.storage.sync.set({ [STORAGE_KEY]: nextDomains });
  } finally {
    isRemoving = false;
    // re-render pour état cohérent
    await renderList();
  }
});

Critères d'acceptation

  • Deux clics rapides sur deux boutons "Supprimer" distincts ne restaurent pas un domaine
  • Les boutons sont désactivés pendant l'opération de suppression
  • L'état du storage est toujours cohérent avec l'affichage après chaque suppression</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.

Copilot AI changed the title [WIP] Fix race condition in simultaneous domain deletions fix: serialize domain deletions with isRemoving flag to prevent race condition Mar 11, 2026
@ormidales ormidales closed this Mar 11, 2026
@ormidales ormidales deleted the copilot/fix-race-condition-domains branch March 11, 2026 13:43
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