This commit is contained in:
2021-12-22 18:51:22 +00:00
parent 14ce0bbf5d
commit 1756f27b5a
30 changed files with 164 additions and 58 deletions

View File

@@ -17,19 +17,24 @@ namespace AyaNova.Util
internal static class ReportRenderManager
{
/*
expired processes are removed by the act of tryign to get a new slot so in this way it still supports running super long reports overnight for example as long as there is no contention
expired processes are removed by the act of trying to get a new slot so in this way it still supports running super long reports overnight for example as long as there is no contention
The other way was by a job that looks for expired processes but that would mean all old jobs would expire all the time so there would be an issue with huge reports never working
*/
//thread safe collection for unordered items, optimized for single thread produce/consume (which is the norm here) but supports multithread produce / consume (which is needed for separate cleanup job)
private static ConcurrentBag<ReportRenderInstanceInfo> _baginstances = new ConcurrentBag<ReportRenderInstanceInfo>();
internal static ConcurrentBag<ReportRenderInstanceInfo> _baginstances;// = new ConcurrentBag<ReportRenderInstanceInfo>();
public class ReportRenderInstanceInfo
static ReportRenderManager()
{
public int ReporterProcessId { get; set; }
public DateTime Expires { get; set; }
_baginstances = new ConcurrentBag<ReportRenderInstanceInfo>();
}
public ReportRenderInstanceInfo(int processId)
internal class ReportRenderInstanceInfo
{
internal int ReporterProcessId { get; set; }
internal DateTime Expires { get; set; }
internal ReportRenderInstanceInfo(int processId)
{
ReporterProcessId = processId;
Expires = DateTime.UtcNow.AddMilliseconds(ServerBootConfig.AYANOVA_REPORT_RENDERING_TIMEOUT);
@@ -37,16 +42,16 @@ namespace AyaNova.Util
}
public static bool RenderSlotAvailable(ILogger log)
internal static bool RenderSlotAvailable(ILogger log)
{
log.LogTrace("RenderSlotAvailable check");
var count = _baginstances.Count;
// #if (DEBUG)
// log.LogInformation($"DBG: RenderSlotAvailable check, there are currently {count} instances in the bag");
// #endif
if (count >= ServerBootConfig.AYANOVA_REPORT_RENDERING_MAX_INSTANCES)
//var count = _baginstances.Count;
#if (DEBUG)
log.LogInformation($"DBG: RenderSlotAvailable check, there are currently {_baginstances.Count} instances in the bag");
#endif
if (_baginstances.Count >= ServerBootConfig.AYANOVA_REPORT_RENDERING_MAX_INSTANCES)
{
log.LogTrace($"RenderSlotAvailable there are no free report rendering slots available, current count is {count}, checking for expired slots to force closed");
log.LogTrace($"RenderSlotAvailable there are no free report rendering slots available, current count is {_baginstances.Count}, checking for expired slots to force closed");
//check for expired and remove
var Instances = _baginstances.ToArray();
var dtNow = DateTime.UtcNow;
@@ -54,9 +59,9 @@ namespace AyaNova.Util
{
if (i.Expires < dtNow)
{
// #if (DEBUG)
// log.LogInformation($"DBG: RenderSlotAvailable attempting kill of expired process {i.ReporterProcessId}");
// #endif
#if (DEBUG)
log.LogInformation($"DBG: RenderSlotAvailable attempting kill of expired process {i.ReporterProcessId}");
#endif
ForceCloseProcess(i, log);
}
}
@@ -65,7 +70,7 @@ namespace AyaNova.Util
return _baginstances.Count < ServerBootConfig.AYANOVA_REPORT_RENDERING_MAX_INSTANCES;
}
private static bool ForceCloseProcess(ReportRenderInstanceInfo instance, ILogger log)
internal static bool ForceCloseProcess(ReportRenderInstanceInfo instance, ILogger log)
{
log.LogTrace($"ForceCloseProcess on instance id {instance.ReporterProcessId} started {instance.Expires.ToString()} utc");
try
@@ -97,16 +102,26 @@ namespace AyaNova.Util
//The process specified by the processId parameter is not running. The identifier might be expired.
_baginstances.TryTake(out instance);
return true;
}
}
}
internal static void AddProcess(int processId)
internal static void AddProcess(int processId, ILogger log)
{
#if (DEBUG)
log.LogInformation($"DBG: RenderSlotAvailable::AddProcess {processId} in the bag");
#endif
_baginstances.Add(new ReportRenderInstanceInfo(processId));
#if (DEBUG)
log.LogInformation($"DBG: RenderSlotAvailable::AddProcess, there are currently {_baginstances.Count} instances in the bag");
#endif
}
internal static void RemoveProcess(int processId, ILogger log)
{
#if (DEBUG)
log.LogInformation($"DBG: RenderSlotAvailable::RemoveProcess {processId} from the bag");
#endif
foreach (var i in _baginstances)
{
if (i.ReporterProcessId == processId)