Fix: Startet nicht / MySQL-Timeout ohne UI (Config- & Startup-Härtung)

Ursachen (App startete aus bin/ bzw. per Doppelklick ohne UI):
1. appsettings.Local.json (MySQL-Connection) wurde NICHT ins Output kopiert und
   nur relativ zum Arbeitsverzeichnis geladen -> leere Connection -> Pomelo fiel
   auf localhost:3306 zurueck -> "Connect Timeout expired".
2. ServerVersion.AutoDetect(conn) oeffnet beim Options-Bau eine blockierende
   DB-Verbindung -> haengt/crasht den Start, wenn die DB nicht erreichbar ist.
3. CopyTradingEngine.StartAsync lud den MarketCache ungeschuetzt -> DB-Fehler
   riss AppHost.Start() ab, bevor die UI erschien.

Fixes:
- csproj: appsettings.Local.json mit ins Output kopieren (CopyToOutputDirectory).
- Program: UseContentRoot(AppContext.BaseDirectory) -> Config wird immer neben
  der EXE gesucht (Main + Smoke-Test).
- ServerVersion fest gepinnt: DatabaseServerVersion.Value = MariaDB 11.8.6 (wie
  am Server erkannt); AddCorePersistence + CopyTradingModule nutzen sie statt
  AutoDetect. Kein blockierender Connect mehr beim Start.
- CopyTradingEngine-Preload in try/catch: DB-Fehler bricht den Start nicht mehr ab.
- Neuer Diagnose-CLI --db-version (gibt @@version aus).

Verifiziert: --smoke-ui aus fremdem Arbeitsverzeichnis laeuft gruen
(3 Accounts / 32 Trader hydriert, alle Views + Launcher OK).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-07-06 10:03:44 +02:00
co-authored by Claude Opus 4.8
parent 6f478e8764
commit f1451b547c
7 changed files with 189 additions and 3 deletions
@@ -53,6 +53,7 @@ namespace PolyTraderSharp.Services
public override async Task StartAsync(CancellationToken cancellationToken)
{
_logger.Info("Starte Preload des MarketCache aus der Datenbank um Flaschenhälse zu vermeiden...");
try
{
// Initialize cache for EVERYTHING in DB that is not closed!
var activeMarkets = _marketRepo.GetActive();
@@ -62,7 +63,7 @@ namespace PolyTraderSharp.Services
{
if (!string.IsNullOrEmpty(md.ClobTokenIds))
{
try
try
{
var tokenIds = System.Text.Json.JsonSerializer.Deserialize<List<string>>(md.ClobTokenIds);
if (tokenIds != null)
@@ -79,6 +80,12 @@ namespace PolyTraderSharp.Services
}
_logger.Info($"MarketCache Preload abgeschlossen: {loaded} Token herangeführt.");
}
catch (Exception ex)
{
// DB nicht erreichbar o.ä.: Start NICHT abbrechen (sonst erscheint keine UI).
// Der Cache füllt sich zur Laufzeit über den MarketSync/Signale nach.
_logger.Error($"MarketCache Preload übersprungen (DB nicht erreichbar?): {ex.Message}");
}
await base.StartAsync(cancellationToken);
}