⬆️ version bump & fix race conditions in API cache and renderers

- Bump Cargo.lock version to `0.3.47`
- Fix race condition in API cache by using unique request keys and proper promise cleanup
  - Avoid duplicate pending requests with `request:${key}` prefix
- Improve renderer snapshot error handling: clear invalid snapshots on failure and always clean up loading flag in `finally`
- Add debounce to renderer refresh logic (500ms) preventing excessive concurrent fetches
  - Use local `currentRendererId` to avoid stale ID usage across async boundaries
This commit is contained in:
2026-04-06 08:06:21 +02:00
parent bb06fbe30e
commit 66ba31b12f
4 changed files with 54 additions and 15 deletions

View File

@@ -92,20 +92,34 @@ class ApiCacheService {
if (cached) return cached;
}
const existing = this.pendingRequests.get(key);
if (existing) {
return existing.promise as Promise<T>;
// Utiliser une clé unique pour éviter les problèmes de race condition
// avec les requêtes en cours qui peuvent être supprimées avant résolution
const requestKey = `request:${key}`;
// Récupérer ou créer la requête
let pendingRequest = this.pendingRequests.get(requestKey);
// Si une requête est en cours et sa promesse n'a pas encore été resolved/rejected
// on retourne directement cette promesse
if (pendingRequest) {
try {
// Attendre la résolution pour s'assurer que c'est toujours valide
return await pendingRequest.promise as T;
} catch (e) {
// La requête a échoué, on continue pour faire une nouvelle requête
this.pendingRequests.delete(requestKey);
}
}
let resolvePromise!: (value: unknown) => void;
let resolvePromise!: (value: T) => void;
let rejectPromise!: (reason: unknown) => void;
const promise = new Promise<unknown>((resolve, reject) => {
const promise = new Promise<T>((resolve, reject) => {
resolvePromise = resolve;
rejectPromise = reject;
});
this.pendingRequests.set(key, {
this.pendingRequests.set(requestKey, {
promise,
subscribers: new Set(),
});
@@ -124,7 +138,7 @@ class ApiCacheService {
resolvePromise(data);
const pending = this.pendingRequests.get(key);
const pending = this.pendingRequests.get(requestKey);
if (pending) {
pending.subscribers.forEach(cb => cb(data));
}
@@ -133,10 +147,10 @@ class ApiCacheService {
rejectPromise(error);
throw error;
} finally {
this.pendingRequests.delete(key);
this.pendingRequests.delete(requestKey);
}
return Promise.reject(new Error('Unreachable'));
return promise;
}
subscribe<T>(endpoint: string, params: Record<string, string | number | boolean>, callback: (data: T) => void): () => void {