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:
parent
355d5ea18d
commit
d78dc14a2b
@ -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
|
||||
|
||||
for (let i = 0; i < maxRetries; i++) {
|
||||
// On demande au worker
|
||||
const addr = await this.worker.getAvailableRelay();
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
"Timeout: Aucun relais disponible après 10s (Handshake non reçu ?)"
|
||||
// 1. Vérification immédiate (Fast path)
|
||||
const existing = Object.values(this.localRelays).find(
|
||||
(addr) => addr && addr !== ""
|
||||
);
|
||||
if (existing) return existing;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
|
||||
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] = "";
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user