Skip to content

[WIP] Implement architectural fixes for EADDRINUSE retry loop#273

Closed
Copilot wants to merge 1 commit into
mainfrom
copilot/implement-arch-fixes-port-race-condition
Closed

[WIP] Implement architectural fixes for EADDRINUSE retry loop#273
Copilot wants to merge 1 commit into
mainfrom
copilot/implement-arch-fixes-port-race-condition

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 16, 2026

  • Analyse der betroffenen Stellen in Go-Launcher, PortManager und server.js abgeschlossen
  • Bestehende Build/Lint/Test-Baseline vor Codeänderungen ausführen und dokumentieren
  • Go-Launcher in build-src/dev-launcher.go passiv machen: checkServerHealth() über Ports 3000-3009, autoFixPort() ohne TCP-Portchecks
  • Go-Launcher in build-src/launcher-gui.go passiv machen: checkServerHealth() über Ports 3000-3009, autoFixPort() ohne TCP-Portchecks
  • app/modules/port-manager.js anpassen: resolvePort(excludePorts = []) und Exclusion für preferred + fallback Ports
  • app/server.js anpassen: failedPorts-Set und EADDRINUSE-Retry mit portManager.resolvePort(Array.from(failedPorts))
  • Relevante Tests ergänzen/aktualisieren und gezielt ausführen
  • Lint/Build/Tests für geänderte Bereiche erneut ausführen und Ergebnis verifizieren
  • app/CHANGELOG.txt mit den durchgeführten Fixes aktualisieren
  • Abschließende Validierung mit parallel_validation durchführen
Original prompt

Setze die architektonischen Fixes für das Port-Race-Condition-Problem (EADDRINUSE Retry Loop) um, die wir zuvor besprochen haben:

  1. Go-Launcher passiv machen (build-src/dev-launcher.go & build-src/launcher-gui.go):

    • Ändere checkServerHealth(), sodass es eine Schleife über die Ports 3000 bis 3009 macht und via HTTP (checkServerHealthOnPort(port)) prüft, ob Node.js antwortet. Wenn ein Port antwortet, setze l.alternativePort = port und gib true zurück.
    • Ändere autoFixPort(), sodass KEINE TCP-Verbindungen (checkPortAvailable) mehr aufgebaut werden, um TIME_WAIT Race-Conditions mit Node.js zu vermeiden. Die Funktion soll nur noch loggen, dass das Port-Management an Node.js delegiert wird.
  2. PortManager Blacklisting (app/modules/port-manager.js):

    • Erweitere resolvePort(excludePorts = []) um den Parameter excludePorts.
    • Ignoriere Ports, die in excludePorts enthalten sind, sowohl beim preferredPort als auch bei den fallbackPorts.
  3. EADDRINUSE Retry-Loop im Server (app/server.js):

    • Finde den server.on('error') Handler ganz unten.
    • Erstelle ein Set namens failedPorts außerhalb des Handlers.
    • Wenn err.code === 'EADDRINUSE' auftritt, füge den aktuellen PORT zu failedPorts hinzu.
    • Rufe portManager.resolvePort(Array.from(failedPorts)) auf, um garantiert den nächsten freien Port zu erhalten und eine Endlosschleife zu verhindern.

Setze das präzise und ohne Verlust von Features um.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: ⏳ Warte auf Port-Freigabe nach Shutdown... macht massive probleme. startet software nicht oder software crashed. warum, und wie fix?

Assistant: Die Ursache für die massiven Probleme und Abstürze liegt in einem architektonischen Konflikt zwischen dem Go-Launcher und dem Node.js-Backend sowie einem kritischen Bug in der Health-Check-Logik des Launchers.

Tiefenanalyse: Warum es kracht

  1. Fataler Bug: Hardcoded Health-Check-Port im Go-Launcher
    Wenn der Go-Launcher nach 15 Sekunden feststellt, dass Port 3000 im TIME_WAIT hängt, wechselt er zu einem alternativen Port (z. B. 3001) und startet Node.js mit PORT=3001.
    Die Funktion checkServerHealth() in build-src/dev-launcher.go und build-src/launcher-gui.go ruft aber weiterhin hartcodiert l.checkServerHealthOnPort(3000) auf.
    Folge: Node.js läuft erfolgreich auf 3001, der Launcher pingt endlos Port 3000, läuft in einen Timeout und tötet/bricht den Startvorgang ab.

  2. Race Condition durch doppeltes Port-Management
    Der Node.js PortManager (app/modules/port-manager.js) ist hochintelligent (sucht nach PIDs, killt alte Instanzen). Der Go-Launcher prüft nur plump via net.Listen("tcp", address), was bei einem Socket im Status TIME_WAIT (nach einem sauberen Shutdown) sofort blockiert. Die 15 Sekunden Wartezeit im Launcher hebeln den intelligenten Node-Manager aus und erzwingen einen unnnötigen Fallback, der dann durch Bug Consolidate documentation for AI assistants and clean repository structure #1 zum Crash führt.


Die Fixes (Produktionsreif)

Du musst sowohl den Go-Launcher als auch die Überlappung der Port-Logik korrigieren. Keine Pseudocode-Lücken, hier sind die vollständigen, bereinigten Blöcke.

1. Fix: Dynamischer Health-Check im Launcher

Ersetze die hartcodierte Methode in beiden Launcher-Dateien (build-src/dev-launcher.go und build-src/launcher-gui.go).

// checkServerHealth checks if the server is responding on the correct selected port
func (l *Launcher) checkServerHealth() bool {
	targetPort := 3000
	if l.alternativePort > 0 {
		targetPort = l.alternativePort
	}
	return l.checkServerHealthOnPort(targetPort)
}
// checkServerHealth checks if the server is responding on the correct selected port
func (l *Launcher) checkServerHealth() bool {
	targetPort := 3000
	if l.alternativePort > 0 {
		targetPort = l.alternativePort
	}
	return l.checkServerHealthOnPort(targetPort)
}

2. Fix: TIME_WAIT Handling & PortManager-Delegation

Wir reduzieren die blockierende Wartezeit im Go-Launcher drastisch auf 3 Sekunden. Da das Node.js-Backend mit seinem PortManager fähig ist, den Port selbst aufzuräumen (action: 'killed_old_instance') oder SO_REUSEADDR Verhalten zu emulieren, übergeben wir Node die Verantwortung, anstatt im Go-Launcher alles aufzuhalten.

Ersetze die Logik in autoFixPort() (ebenfalls in beiden .go Dateien):

// autoFixPort checks if port 3000 is available and logs status
func (l *Launcher) autoFixPort() {
	l.logger.Println("[INFO] Checking if port 3000 is available...")

	if l.checkP...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants