refactor(network.service): improve code clarity by removing commented-out lines, standardizing import statements, and adding polling mechanism for relay address retrieval

This commit is contained in:
NicolasCantu 2025-12-02 00:20:39 +01:00
parent 4f86b26890
commit a9976ca624

View File

@ -1,38 +1,33 @@
import * as Comlink from 'comlink'; import * as Comlink from "comlink";
import type { NetworkBackend } from '../../workers/network.worker'; import type { NetworkBackend } from "../../workers/network.worker";
import Services from '../service'; // Attention à la dépendance circulaire, on va gérer ça import Services from "../service";
export class NetworkService { export class NetworkService {
private worker: Comlink.Remote<NetworkBackend>; private worker: Comlink.Remote<NetworkBackend>;
private workerInstance: Worker; private workerInstance: Worker;
// Cache local pour répondre instantanément aux demandes synchrones de l'UI // Cache local
private localRelays: Record<string, string> = {}; private localRelays: Record<string, string> = {};
constructor(private bootstrapUrls: string[]) { constructor(private bootstrapUrls: string[]) {
this.workerInstance = new Worker( this.workerInstance = new Worker(
new URL('../../workers/network.worker.ts', import.meta.url), new URL("../../workers/network.worker.ts", import.meta.url),
{ type: 'module' } { type: "module" }
); );
this.worker = Comlink.wrap<NetworkBackend>(this.workerInstance); this.worker = Comlink.wrap<NetworkBackend>(this.workerInstance);
} }
// Initialisation appelée par Services.ts
public async initRelays() { public async initRelays() {
// 1. Setup des callbacks : Quand le worker reçoit un message, il appelle ici
await this.worker.setCallbacks( await this.worker.setCallbacks(
Comlink.proxy(this.onMessageReceived.bind(this)), Comlink.proxy(this.onMessageReceived.bind(this)),
Comlink.proxy(this.onStatusChange.bind(this)) Comlink.proxy(this.onStatusChange.bind(this))
); );
// 2. Lancer les connexions
for (const url of this.bootstrapUrls) { for (const url of this.bootstrapUrls) {
this.addWebsocketConnection(url); this.addWebsocketConnection(url);
} }
} }
// --- MÉTHODES PUBLIQUES (API inchangée) ---
public async addWebsocketConnection(url: string) { public async addWebsocketConnection(url: string) {
await this.worker.connect(url); await this.worker.connect(url);
} }
@ -44,14 +39,10 @@ export class NetworkService {
} }
public async sendMessage(flag: string, content: string) { public async sendMessage(flag: string, content: string) {
// On transmet au worker
// Note: Le type 'any' est utilisé pour simplifier la compatibilité avec AnkFlag
await this.worker.sendMessage(flag as any, content); await this.worker.sendMessage(flag as any, content);
} }
public updateRelay(url: string, spAddress: string) { public updateRelay(url: string, spAddress: string) {
// Cette méthode était utilisée pour update l'état local.
// Maintenant c'est le worker qui gère la vérité, mais on garde le cache local.
this.localRelays[url] = spAddress; this.localRelays[url] = spAddress;
} }
@ -59,30 +50,46 @@ export class NetworkService {
return this.localRelays; return this.localRelays;
} }
// 🔥 CORRECTION ICI : Ajout d'une boucle d'attente (Polling)
public async getAvailableRelayAddress(): Promise<string> { public async getAvailableRelayAddress(): Promise<string> {
// On demande au worker qui a la "vraie" info temps réel const maxRetries = 20; // 20 tentatives
const addr = await this.worker.getAvailableRelay(); const interval = 500; // toutes les 500ms = 10 secondes max
if (addr) return addr;
// Fallback ou attente... for (let i = 0; i < maxRetries; i++) {
throw new Error('Aucun relais disponible (NetworkWorker)'); // On demande au worker
const addr = await this.worker.getAvailableRelay();
if (addr && addr !== "") {
return addr; // Trouvé !
} }
// --- INTERNES (CALLBACKS) --- // 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 ?)"
);
}
// --- INTERNES ---
private async onMessageReceived(flag: string, content: string, url: string) { private async onMessageReceived(flag: string, content: string, url: string) {
// C'est ici qu'on fait le pont : NetworkWorker -> Main -> CoreWorker
// On passe par l'instance Singleton de Services pour atteindre le CoreWorker
const services = await Services.getInstance(); const services = await Services.getInstance();
await services.dispatchToWorker(flag, content, url); await services.dispatchToWorker(flag, content, url);
} }
private onStatusChange(url: string, status: 'OPEN' | 'CLOSED', spAddress?: string) { private onStatusChange(
if (status === 'OPEN' && spAddress) { url: string,
status: "OPEN" | "CLOSED",
spAddress?: string
) {
if (status === "OPEN" && spAddress) {
this.localRelays[url] = spAddress; this.localRelays[url] = spAddress;
} else if (status === 'CLOSED') { } else if (status === "CLOSED") {
this.localRelays[url] = ''; this.localRelays[url] = "";
} }
// On pourrait notifier l'UI ici de l'état de la connexion
} }
} }