Report rendering handler to prevent linux from crashing on too much reporting at once

This commit is contained in:
2021-10-27 00:11:57 +00:00
parent 35c39c30a7
commit ae2b42065a
7 changed files with 103 additions and 24 deletions

View File

@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
namespace AyaNova.Util
{
@@ -11,18 +12,50 @@ namespace AyaNova.Util
/// also zombie process issues in linux etc, this just ensures it's safe
/// This is triggered when a report is rendered
/// </summary>
internal static class ReportingProcessCache
internal static class ReportProcessorManager
{
internal static int ReporterProcessId { get; set; } = -1;
internal static DateTime Started { get; set; }
internal static void EnsureReporterAvailable(int timeOutMilliSeconds)
internal async static Task EnsureReporterAvailableAsync(ILogger log)
{
if (ReporterProcess() == null) return;
Process reportProcess = ReporterProcess();
if (reportProcess == null)
{
return;
}
//await it's completion in the specified timeout
int HardTimeout = ServerBootConfig.AYANOVA_REPORT_RENDERING_TIMEOUT;
//don't wait forever, hard cap of 3 minutes regardless of setting
if (HardTimeout > 180000) HardTimeout = 180000;
bool keepOnWaiting = true;
while (keepOnWaiting)
{
//don't check continually
await Task.Delay(500);
//check process is still running
if (reportProcess?.HasExited == false)
{
//time to kill it?
if ((DateTime.UtcNow - Started).TotalMilliseconds > HardTimeout)
{
log.LogInformation($"Report processor did not complete in {HardTimeout}ms and will be force stopped");
reportProcess.Kill();
keepOnWaiting = false;
}
}
else
{
log.LogDebug($"EnsureReporterAvailableAsync Reporter processor completed normally");
keepOnWaiting = false;
}
};
ReporterProcessId = -1;
Started = DateTime.MinValue;
return;
}
internal static void FlagNewProcess(int processId)
internal static void RecordNewReportGeneratorProcess(int processId)
{
ReporterProcessId = processId;
Started = DateTime.UtcNow;

View File

@@ -14,7 +14,7 @@ namespace AyaNova.Util
//############################################################################################################
//STATIC HARD CODED COMPILE TIME DEFAULTS NOT SET THROUGH CONFIG
internal const int FAILED_AUTH_DELAY = 3000;//ms
internal const int REPORT_RENDERING_OPERATION_TIMEOUT = 20000;//ms
//UPLOAD LIMITS 1048576 = 1MiB for testing 10737420000 10737418240 10,737,418,240
internal const long MAX_ATTACHMENT_UPLOAD_BYTES = 10737420000;//slight bit of overage as 10737418241=10GiB
internal const long MAX_LOGO_UPLOAD_BYTES = 512000;//500KiB limit
@@ -60,6 +60,8 @@ namespace AyaNova.Util
//API
internal static string AYANOVA_JWT_SECRET { get; set; }
internal static string AYANOVA_USE_URLS { get; set; }
internal static int AYANOVA_REPORT_RENDERING_TIMEOUT { get; set; }
//DATABASE
internal static string AYANOVA_DB_CONNECTION { get; set; }
@@ -159,6 +161,9 @@ namespace AyaNova.Util
AYANOVA_JWT_SECRET = config.GetValue<string>("AYANOVA_JWT_SECRET");
int? nTemp = config.GetValue<int?>("AYANOVA_REPORT_RENDERING_TIMEOUT");
AYANOVA_REPORT_RENDERING_TIMEOUT = (null == nTemp) ? 30000 : (int)nTemp;
//DB
AYANOVA_DB_CONNECTION = config.GetValue<string>("AYANOVA_DB_CONNECTION");
bTemp = config.GetValue<bool?>("AYANOVA_PERMANENTLY_ERASE_DATABASE");