From 0666f87b4b55e3813f264ee25a49f19fec452ebf Mon Sep 17 00:00:00 2001 From: Joseph Milazzo Date: Mon, 18 Oct 2021 13:30:58 -0700 Subject: [PATCH] Stat upload will now schedule itself between midnight and 6am in server time for upload. (#688) --- API/Services/Tasks/StatsService.cs | 32 ++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/API/Services/Tasks/StatsService.cs b/API/Services/Tasks/StatsService.cs index 47087fc8d..70eaecf7d 100644 --- a/API/Services/Tasks/StatsService.cs +++ b/API/Services/Tasks/StatsService.cs @@ -10,6 +10,7 @@ using API.DTOs.Stats; using API.Interfaces; using API.Interfaces.Services; using API.Services.Clients; +using Hangfire; using Kavita.Common; using Kavita.Common.EnvironmentInfo; using Microsoft.EntityFrameworkCore; @@ -67,14 +68,8 @@ namespace API.Services.Tasks { try { - _logger.LogDebug("Finalizing Stats collection flow"); - var data = await GetExistingData(); - - _logger.LogDebug("Sending data to the Stats server"); await _client.SendDataToStatsServer(data); - - _logger.LogDebug("Deleting the file from disk"); if (FileExists) File.Delete(FinalPath); } catch (Exception ex) @@ -84,6 +79,10 @@ namespace API.Services.Tasks } } + /// + /// Due to all instances firing this at the same time, we can DDOS our server. This task when fired will schedule the task to be run + /// randomly over a 6 hour spread + /// public async Task CollectAndSendStatsData() { var allowStatCollection = (await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).AllowStatCollection; @@ -92,6 +91,27 @@ namespace API.Services.Tasks _logger.LogDebug("User has opted out of stat collection, not registering tasks"); return; } + + var rnd = new Random(); + var offset = rnd.Next(0, 6); + if (offset == 0) + { + await SendData(); + } + else + { + _logger.LogInformation("KavitaStats upload has been schedule to run in {Offset} hours", offset); + BackgroundJob.Schedule(() => SendData(), DateTimeOffset.Now.AddHours(offset)); + } + } + + /// + /// This must be public for Hangfire. Do not call this directly. + /// + // ReSharper disable once MemberCanBePrivate.Global + public async Task SendData() + { + _logger.LogDebug("Sending data to the Stats server"); await CollectRelevantData(); await FinalizeStats(); }