From d78dc14a2b91ee3503269cbbeef0c2c54584fa32 Mon Sep 17 00:00:00 2001 From: NicolasCantu Date: Tue, 2 Dec 2025 00:54:14 +0100 Subject: [PATCH] refactor(network.service): implement event-driven mechanism for relay readiness, replacing polling with promise-based handling for improved efficiency and clarity --- src/services/core/network.service.ts | 52 ++++++++++++++++++---------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/src/services/core/network.service.ts b/src/services/core/network.service.ts index 3dae1ab..c59b409 100644 --- a/src/services/core/network.service.ts +++ b/src/services/core/network.service.ts @@ -9,6 +9,10 @@ export class NetworkService { // Cache local private localRelays: Record = {}; + // Mécanisme d'attente (Events) + private relayReadyResolver: ((addr: string) => void) | null = null; + private relayReadyPromise: Promise | null = null; + constructor(private bootstrapUrls: string[]) { this.workerInstance = new Worker( new URL("../../workers/network.worker.ts", import.meta.url), @@ -42,36 +46,47 @@ export class NetworkService { await this.worker.sendMessage(flag as any, content); } + // Cette méthode est appelée par le Worker (via Services.ts) ou par onStatusChange public updateRelay(url: string, spAddress: string) { this.localRelays[url] = spAddress; + + // ✨ EVENT TRIGGER : Si quelqu'un attendait un relais, on le débloque ! + if (spAddress && spAddress !== "" && this.relayReadyResolver) { + this.relayReadyResolver(spAddress); + this.relayReadyResolver = null; + this.relayReadyPromise = null; + } } public getAllRelays() { return this.localRelays; } - // 🔥 CORRECTION ICI : Ajout d'une boucle d'attente (Polling) public async getAvailableRelayAddress(): Promise { - const maxRetries = 20; // 20 tentatives - const interval = 500; // toutes les 500ms = 10 secondes max + // 1. Vérification immédiate (Fast path) + const existing = Object.values(this.localRelays).find( + (addr) => addr && addr !== "" + ); + if (existing) return existing; - for (let i = 0; i < maxRetries; i++) { - // On demande au worker - const addr = await this.worker.getAvailableRelay(); + // 2. Si pas encore là, on crée une "barrière" (Promise) + if (!this.relayReadyPromise) { + console.log("[NetworkService] ⏳ Attente d'un événement Handshake..."); + this.relayReadyPromise = new Promise((resolve, reject) => { + this.relayReadyResolver = resolve; - if (addr && addr !== "") { - return addr; // Trouvé ! - } - - // Pas encore là ? On attend un peu... - if (i === 0) - console.log("[NetworkService] ⏳ Attente du Handshake relais..."); - await new Promise((r) => setTimeout(r, interval)); + // Timeout de sécurité (10s) pour ne pas bloquer indéfiniment + setTimeout(() => { + if (this.relayReadyResolver) { + reject(new Error("Timeout: Aucun relais reçu après 10s")); + this.relayReadyResolver = null; + this.relayReadyPromise = null; + } + }, 10000); + }); } - throw new Error( - "Timeout: Aucun relais disponible après 10s (Handshake non reçu ?)" - ); + return this.relayReadyPromise; } // --- INTERNES --- @@ -87,7 +102,8 @@ export class NetworkService { spAddress?: string ) { if (status === "OPEN" && spAddress) { - this.localRelays[url] = spAddress; + // Met à jour et déclenche potentiellement le resolve() + this.updateRelay(url, spAddress); } else if (status === "CLOSED") { this.localRelays[url] = ""; }