using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Hosting; using MongoDB.Driver; using PolyTrader.Core.Persistence; using PolyTraderSharp.Models; namespace PolyTraderSharp.Services { /// /// Hydriert den TradingState (Accounts, Demo-Positionen, Trader) EINMALIG beim App-Start. /// Registriert als erster IHostedService, damit die Hydration abgeschlossen ist, bevor die /// Trading-BackgroundServices (TraderMonitor, CopyTradingEngine, ...) ihre ExecuteAsync /// starten. Behebt den Startup-Race, bei dem Services gegen einen leeren State anliefen /// (früher lag diese Logik in frm_main.LoadDatabaseAndState und lief erst NACH AppHost.Start()). /// public class StartupHydrationService : IHostedService { private readonly TradingState _state; private readonly CopyTradingState _copyState; private readonly IAccountRepository _accountRepo; private readonly IPositionRepository _positionRepo; private readonly IMongoDatabase _db; private readonly TerminalLogger _logger; public StartupHydrationService( TradingState state, CopyTradingState copyState, IAccountRepository accountRepo, IPositionRepository positionRepo, IMongoDatabase db, TerminalLogger logger) { _state = state; _copyState = copyState; _accountRepo = accountRepo; _positionRepo = positionRepo; _db = db; _logger = logger; } public Task StartAsync(CancellationToken cancellationToken) { try { foreach (var acc in _accountRepo.GetAll()) { if (acc.IsDemo) { foreach (var pos in _positionRepo.GetDemo(acc.AccountId)) { acc.OpenPositions.TryAdd(pos.TokenId, pos); } } _state.Accounts[acc.AccountId] = acc; } // Trader (TrackedTrader) sind aktuell noch modulnah; bis zum Trader-Repo in // Phase 5 direkt aus der "trackers"-Collection geladen. var tradersCol = _db.GetCollection("trackers"); foreach (var trd in tradersCol.Find(_ => true).ToList()) { _copyState.Traders[trd.Id] = trd; } _logger.Info($"Startup-Hydration abgeschlossen: {_state.Accounts.Count} Accounts, {_copyState.Traders.Count} Trader geladen."); } catch (System.Exception ex) { _logger.Error($"Startup-Hydration fehlgeschlagen: {ex.Message}"); } return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; } }