refactor(network.service): implement event-driven mechanism for relay readiness, replacing polling with promise-based handling for improved efficiency and clarity

This commit is contained in:
NicolasCantu 2025-12-02 00:54:14 +01:00
parent 355d5ea18d
commit d78dc14a2b

View File

@ -9,6 +9,10 @@ export class NetworkService {
// Cache local
private localRelays: Record<string, string> = {};
// Mécanisme d'attente (Events)
private relayReadyResolver: ((addr: string) => void) | null = null;
private relayReadyPromise: Promise<string> | 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<string> {
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<string>((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] = "";
}