diff --git a/src/Managing.Application/Grains/PriceFetcher15MinGrain.cs b/src/Managing.Application/Grains/PriceFetcher15MinGrain.cs index 957b9be9..aa94831a 100644 --- a/src/Managing.Application/Grains/PriceFetcher15MinGrain.cs +++ b/src/Managing.Application/Grains/PriceFetcher15MinGrain.cs @@ -24,6 +24,7 @@ public class PriceFetcher15MinGrain : Grain, IPriceFetcher15MinGrain, IRemindabl private readonly IGrainFactory _grainFactory; private const string FetchPricesReminderName = "Fetch15minPricesReminder"; + private IDisposable _timer; // Predefined lists of trading parameters to fetch private static readonly TradingExchanges[] SupportedExchanges = @@ -51,15 +52,24 @@ public class PriceFetcher15MinGrain : Grain, IPriceFetcher15MinGrain, IRemindabl { _logger.LogInformation("{0} activated", nameof(PriceFetcher15MinGrain)); - // Register a reminder to fetch prices every 5 minutes + // Register a reminder to enable timer if not existing await this.RegisterOrUpdateReminder( FetchPricesReminderName, - TimeSpan.FromMinutes(5), + TimeSpan.FromSeconds(5), TimeSpan.FromMinutes(5)); await base.OnActivateAsync(cancellationToken); } + public override async Task OnDeactivateAsync(DeactivationReason reason, CancellationToken cancellationToken) + { + _logger.LogInformation("{0} deactivating. Reason: {Reason}", + nameof(PriceFetcher15MinGrain), reason.Description); + + StopAndDisposeTimer(); + await base.OnDeactivateAsync(reason, cancellationToken); + } + public async Task FetchAndPublishPricesAsync() { try @@ -167,23 +177,46 @@ public class PriceFetcher15MinGrain : Grain, IPriceFetcher15MinGrain, IRemindabl } } - private static int GetTimeframeMinutes(Timeframe timeframe) => timeframe switch + /// + /// Starts the Orleans timer for periodic price fetching + /// + private void RegisterAndStartTimer() { - Timeframe.OneMinute => 1, - Timeframe.FiveMinutes => 5, - Timeframe.FifteenMinutes => 15, - Timeframe.ThirtyMinutes => 30, - Timeframe.OneHour => 60, - Timeframe.FourHour => 240, - Timeframe.OneDay => 1440, - _ => 1 - }; + if (_timer != null) return; - public async Task ReceiveReminder(string reminderName, TickStatus status) + _timer = this.RegisterGrainTimer( + async _ => await FetchAndPublishPricesAsync(), + new GrainTimerCreationOptions + { + Period = TimeSpan.FromMinutes(15), + DueTime = TimeSpan.FromSeconds(1), + KeepAlive = true + }); + + _logger.LogInformation("{0} timer registered and started", nameof(PriceFetcher15MinGrain)); + } + + private void StopAndDisposeTimer() + { + if (_timer != null) + { + _timer?.Dispose(); + _timer = null; + _logger.LogInformation("{0} timer stopped and disposed", nameof(PriceFetcher15MinGrain)); + } + } + + public Task ReceiveReminder(string reminderName, TickStatus status) { if (reminderName == FetchPricesReminderName) { - await FetchAndPublishPricesAsync(); + // Only enable timer if not existing anymore + if (_timer == null) + { + RegisterAndStartTimer(); + } } + + return Task.CompletedTask; } } \ No newline at end of file