[Bug] Race condition sur deals_raw.json — écritures concurrentes sans lock #24

Closed
opened 2026-08-05 11:03:40 -04:00 by NixCyRy · 0 comments
NixCyRy commented 2026-08-05 11:03:40 -04:00 (Migrated from github.com)

Problème

Plusieurs fonctions font un read-modify-write du fichier deals_raw.json sans aucun verrou :

  • fetch_all_deals_raw() — lancé par trigger_raw_refresh_async() dans un thread daemon
  • add_to_raw_deals() — appelé par les routes admin /api/admin/food/show
  • remove_from_raw_deals() — appelé par les routes admin /api/admin/food/hide
  • load_raw_deals() — lecture

Deux écritures simultanées peuvent corrompre le JSON ou perdre des données.

De plus, la variable globale DEALS_BUILDING utilise un pattern check-then-set sans synchronisation (if DEALS_BUILDING: return False ... DEALS_BUILDING = True).

Fichier

backend/utils/foods_helpers.py

Fix

  1. threading.Lock global autour de toutes les opérations fichier
  2. Remplacer DEALS_BUILDING par threading.Lock(acquire(blocking=False)) ou threading.Event
import threading

_deals_file_lock = threading.Lock()

def add_to_raw_deals(food_name, deals):
    with _deals_file_lock:
        # read-modify-write

Sévérité

🔴 Critical — corruption de données possible en production.

## Problème Plusieurs fonctions font un read-modify-write du fichier `deals_raw.json` sans aucun verrou : - `fetch_all_deals_raw()` — lancé par `trigger_raw_refresh_async()` dans un thread daemon - `add_to_raw_deals()` — appelé par les routes admin `/api/admin/food/show` - `remove_from_raw_deals()` — appelé par les routes admin `/api/admin/food/hide` - `load_raw_deals()` — lecture Deux écritures simultanées peuvent corrompre le JSON ou perdre des données. De plus, la variable globale `DEALS_BUILDING` utilise un pattern check-then-set sans synchronisation (`if DEALS_BUILDING: return False` ... `DEALS_BUILDING = True`). ## Fichier `backend/utils/foods_helpers.py` ## Fix 1. `threading.Lock` global autour de toutes les opérations fichier 2. Remplacer `DEALS_BUILDING` par `threading.Lock(acquire(blocking=False))` ou `threading.Event` ```python import threading _deals_file_lock = threading.Lock() def add_to_raw_deals(food_name, deals): with _deals_file_lock: # read-modify-write ``` ## Sévérité 🔴 Critical — corruption de données possible en production.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
SlopVibe-org/nutri-food#24
No description provided.