From d2dbee9a5ff7e73f616dc3aba47466295fb04167 Mon Sep 17 00:00:00 2001 From: cryptooda Date: Mon, 15 Sep 2025 00:42:24 +0700 Subject: [PATCH] Fix unsubscribe + reduce bot update db query --- .../Grains/CandleStoreGrain.cs | 20 ++++++++++++++++--- .../Grains/PriceFetcherGrain.cs | 2 +- .../ManageBot/BotService.cs | 10 +++++++++- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/Managing.Application/Grains/CandleStoreGrain.cs b/src/Managing.Application/Grains/CandleStoreGrain.cs index 2949020e..bb9b9272 100644 --- a/src/Managing.Application/Grains/CandleStoreGrain.cs +++ b/src/Managing.Application/Grains/CandleStoreGrain.cs @@ -67,11 +67,25 @@ public class CandleStoreGrain : Grain, ICandleStoreGrain, IAsyncObserver public override async Task OnDeactivateAsync(DeactivationReason reason, CancellationToken cancellationToken) { - // Unsubscribe from the stream + // Unsubscribe from the stream with proper error handling if (_streamSubscription != null) { - await _streamSubscription.UnsubscribeAsync(); - _streamSubscription = null; + try + { + await _streamSubscription.UnsubscribeAsync(); + _logger.LogDebug("Successfully unsubscribed from stream for grain {GrainKey}", this.GetPrimaryKeyString()); + } + catch (Exception ex) + { + // Log the error but don't throw - this is common during shutdown when + // the pub-sub rendezvous grain may already be deactivated + _logger.LogWarning(ex, "Failed to unsubscribe from stream during deactivation for grain {GrainKey}. This is normal during shutdown.", + this.GetPrimaryKeyString()); + } + finally + { + _streamSubscription = null; + } } await base.OnDeactivateAsync(reason, cancellationToken); diff --git a/src/Managing.Application/Grains/PriceFetcherGrain.cs b/src/Managing.Application/Grains/PriceFetcherGrain.cs index 3522eb1c..e237026e 100644 --- a/src/Managing.Application/Grains/PriceFetcherGrain.cs +++ b/src/Managing.Application/Grains/PriceFetcherGrain.cs @@ -129,7 +129,7 @@ public class PriceFetcherGrain : Grain, IPriceFetcherGrain, IRemindable // Get the last candle date from database var existingCandles = await _candleRepository.GetCandles(exchange, ticker, timeframe, - DateTime.UtcNow.AddDays(-30), DateTime.UtcNow.AddDays(1), 20); + DateTime.UtcNow.AddDays(-30), DateTime.UtcNow.AddDays(1), 1); var isFirstCall = !existingCandles.Any(); diff --git a/src/Managing.Application/ManageBot/BotService.cs b/src/Managing.Application/ManageBot/BotService.cs index 1a7e185f..5f012c20 100644 --- a/src/Managing.Application/ManageBot/BotService.cs +++ b/src/Managing.Application/ManageBot/BotService.cs @@ -296,6 +296,8 @@ namespace Managing.Application.ManageBot var existingBot = await _botRepository.GetBotByIdentifierAsync(bot.Identifier); + + // Check if bot already exists in database await ServiceScopeHelpers.WithScopedService( _scopeFactory, @@ -311,7 +313,13 @@ namespace Managing.Application.ManageBot "Created new bot statistics for bot {BotId}: Wins={Wins}, Losses={Losses}, PnL={PnL}, ROI={ROI}%, Volume={Volume}, Fees={Fees}", bot.Identifier, bot.TradeWins, bot.TradeLosses, bot.Pnl, bot.Roi, bot.Volume, bot.Fees); } - else + else if (existingBot.Status != bot.Status + || existingBot.Pnl != Math.Round(bot.Pnl, 8) + || existingBot.Roi != Math.Round(bot.Roi, 8) + || existingBot.Volume != Math.Round(bot.Volume, 8) + || existingBot.Fees != Math.Round(bot.Fees, 8) + || existingBot.LongPositionCount != bot.LongPositionCount + || existingBot.ShortPositionCount != bot.ShortPositionCount) { _tradingBotLogger.LogInformation("Update bot statistics for bot {BotId}", bot.Identifier);