Aller au contenu principal

Race Conditions - Correction du Dashboard Étudiant

Date : 23 février 2026 Auteur : GNIMAGNON Arès Statut : Corrigé


Problème

Sur la page /student/search (et potentiellement d'autres pages du dashboard étudiant), l'affichage des données était incohérent :

  • Parfois affichait 0 offre
  • Parfois affichait le bon nombre d'offres avec les détails

Cause racine

Race condition dans le flux de chargement des données :

  1. Cache backend TTL trop long (5 minutes) - Données pouvant être obsolètes
  2. Plusieurs requêtes HTTP concurrentes sans annulation :
    • Requête A : avec filtres initiaux (vides)
    • Requête B : avec filtres du profil étudiant
    • Celle qui arrive en dernier écrase l'état data

Solution implémentée

1. AbortController (Frontend)

Tous les hooks concernés ont été modifiés pour utiliser AbortController afin d'annuler les requêtes précédentes :

const abortControllerRef = useRef<AbortController | null>(null);

const fetchData = useCallback(async (signal?: AbortSignal) => {
// Annuler toute requête en cours
if (abortControllerRef.current) {
abortControllerRef.current.abort();
}

// Créer un nouveau contrôleur
const controller = new AbortController();
abortControllerRef.current = controller;

// Utiliser le signal pour l'API
const result = await apiCall(controller.signal);
}, []);

// Nettoyage dans useEffect
useEffect(() => {
const controller = new AbortController();
fetchData(controller.signal);
return () => controller.abort();
}, [fetchData]);

2. Réduction du TTL du cache (Backend)

Le TTL du cache Redis pour les offres publiques a été réduit :

AvantAprès
300s (5 min)60s (1 min)

Fichier : backend/app/api/v1/routers/themes.py


Hooks corrigés

Priorité HAUTE (corrigés)

HookFichierProblème
useStudentSearchhooks/student/useStudentSearch.tsRequêtes concurrentes avec filtres
useStudentProfilehooks/student/useStudentProfile.tsPas d'annulation + background refresh
useStudentDocumentshooks/student/useStudentDocuments.tsPromise.all parallèle sans annulation

Priorité MOYENNE (corrigés)

HookFichierProblème
useStudentQualificationshooks/student/useStudentQualifications.tsPas de cancellation → ✅ Corrigé
useStudentApplicationshooks/student/useStudentApplications.tsFlag cancelled faible → ✅ Corrigé

Priorité MOYENNE (corrigés)

HookFichierProblème
useStudentDashboardhooks/student/useStudentDashboard.tsFlag cancelled faible → ✅ Corrigé
useInternshipDetailshooks/student/useInternshipDetails.tsFlag mounted faible → ✅ Corrigé
useBinomeManagementhooks/student/useBinomeManagement.tsPas de cancellation → ✅ Corrigé

Hooks OK (pas de correction needed)

  • useCurrentInternship - Utilise React Query
  • useBinome - Utilise React Query

Fichiers modifiés

Backend

  • backend/app/api/v1/routers/themes.py - TTL cache réduit

Frontend - Services

  • stage-connect/services/student.search.services.ts - Support AbortSignal
  • stage-connect/services/student.profile.services.ts - Support AbortSignal
  • stage-connect/services/student.documents.services.ts - Support AbortSignal
  • stage-connect/services/student.qualifications.services.ts - Support AbortSignal
  • stage-connect/services/student.applications.services.ts - Support AbortSignal
  • stage-connect/services/student.dashboard.services.ts - Support AbortSignal
  • stage-connect/services/student.pairs.services.ts - Support AbortSignal

Frontend - Hooks

  • stage-connect/hooks/student/useStudentSearch.ts - AbortController
  • stage-connect/hooks/student/useStudentProfile.ts - AbortController
  • stage-connect/hooks/student/useStudentDocuments.ts - AbortController
  • stage-connect/hooks/student/useStudentQualifications.ts - AbortController
  • stage-connect/hooks/student/useStudentApplications.ts - AbortController
  • stage-connect/hooks/student/useStudentDashboard.ts - AbortController
  • stage-connect/hooks/student/useInternshipDetails.ts - AbortController
  • stage-connect/hooks/student/useBinomeManagement.ts - AbortController

Comment tester

  1. Ouvrir /student/search plusieurs fois
  2. Vérifier que le nombre d'offres est cohérent
  3. Vérifier que les filtres du profil sont bien appliqués
  4. Tester avec différents profils étudiants
  5. Tester /student/profile et /student/documents

Bonnes pratiques pour les nouveaux hooks

Lors de la création d'un nouveau hook qui fetch des données :

  1. Toujours utiliser AbortController pour annuler les requêtes
  2. Gérer les AbortError dans le catch
  3. Nettoyer dans le useEffect (return avec abort)
  4. Réduire le cache backend si les données changent fréquemment
useEffect(() => {
const controller = new AbortController();
loadData(controller.signal);
return () => controller.abort();
}, [loadData]);