From 35c39c30a7aec6c7daf5a5beea7758b0c6e6b84d Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Tue, 26 Oct 2021 22:14:16 +0000 Subject: [PATCH] --- server/AyaNova/biz/ReportBiz.cs | 22 +++---- server/AyaNova/util/ReportingProcessCache.cs | 68 ++++++++++++++++++++ 2 files changed, 76 insertions(+), 14 deletions(-) create mode 100644 server/AyaNova/util/ReportingProcessCache.cs diff --git a/server/AyaNova/biz/ReportBiz.cs b/server/AyaNova/biz/ReportBiz.cs index 6854c3f2..f332ca26 100644 --- a/server/AyaNova/biz/ReportBiz.cs +++ b/server/AyaNova/biz/ReportBiz.cs @@ -11,6 +11,7 @@ using EnumsNET; using PuppeteerSharp; using Newtonsoft.Json.Linq; using System.Threading; +using System; namespace AyaNova.Biz { @@ -432,6 +433,10 @@ namespace AyaNova.Biz //initialization log.LogDebug("Initializing report system"); var ReportJSFolderPath = Path.Combine(ServerBootConfig.AYANOVA_CONTENT_ROOT_PATH, "resource", "rpt"); + + //Ensure last reporting op has completed + ReportingProcessCache.EnsureReporterAvailable(ServerBootConfig.REPORT_RENDERING_OPERATION_TIMEOUT); + var lo = new LaunchOptions { Headless = true }; bool isWindows = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows); if (!isWindows) @@ -487,11 +492,8 @@ namespace AyaNova.Biz using (var browser = await Puppeteer.LaunchAsync(lo)) using (var page = await browser.NewPageAsync()) { - - - - //see catch block - var ChromiumProcessID = browser.Process.Id; + //mark this process so it can be cancelled if it times out + ReportingProcessCache.FlagNewProcess(browser.Process.Id); try { @@ -710,15 +712,7 @@ namespace AyaNova.Biz //render to pdf and return log.LogDebug($"Calling render page contents to PDF"); - - //============== TESTING ================= - var process = System.Diagnostics.Process.GetProcessById(ChromiumProcessID); - if (ChromiumProcessID > 0 && process?.HasExited == false) - { - log.LogError($"Error during render, Chromium process (pid {ChromiumProcessID}) still active, forcing it to stop now"); - process.Kill(); - } - //============================================ + await page.PdfAsync(outputFullPath, PdfOptions);//###### TODO: SLOW NEEDS TIMEOUT HERE ONCE SUPPORTED, open bug: https://github.com/hardkoded/puppeteer-sharp/issues/1710 log.LogDebug($"Completed, returning results"); diff --git a/server/AyaNova/util/ReportingProcessCache.cs b/server/AyaNova/util/ReportingProcessCache.cs new file mode 100644 index 00000000..6f65007c --- /dev/null +++ b/server/AyaNova/util/ReportingProcessCache.cs @@ -0,0 +1,68 @@ +using System; +using System.Diagnostics; + + +namespace AyaNova.Util +{ + + /// + /// Used by reporting system to ensure headless browsers don't hang around in an untimely manner + /// needed due to bugs in puppeteersharp where it won't close the browser on timeout properly + /// also zombie process issues in linux etc, this just ensures it's safe + /// This is triggered when a report is rendered + /// + internal static class ReportingProcessCache + { + internal static int ReporterProcessId { get; set; } = -1; + internal static DateTime Started { get; set; } + + internal static void EnsureReporterAvailable(int timeOutMilliSeconds) + { + if (ReporterProcess() == null) return; + //await it's completion in the specified timeout + } + + internal static void FlagNewProcess(int processId) + { + ReporterProcessId = processId; + Started = DateTime.UtcNow; + } + + private static Process ReporterProcess() + { + if (ReporterProcessId == -1) return null; + try + { + return Process.GetProcessById(ReporterProcessId); + } + catch (ArgumentException) + { + return null;//no process available / not running + } + } + + + /* + //Is the report generator (browser) already running? + if(ReportingProcessCache.ReporterProcess()!=null){ + //there is an existing process in action, let's wait for timeout seconds and kill it if it's still running before proceeding + //first check to see if it's still actually running or not: + var process = System.Diagnostics.Process.GetProcessById(ReportingProcessCache.ReporterProcessId); + // if (ChromiumProcessID > 0 && process?.HasExited == false) + // { + // log.LogError($"Error during render, Chromium process (pid {ChromiumProcessID}) still active, forcing it to stop now"); + // process.Kill(); + // } + + bool keepOnWaiting=true; + while(keepOnWaiting){ + var v= DateTime.UtcNow-ReportingProcessCache.Started; + if(v.TotalSeconds> ServerBootConfig.REPORT_RENDERING_OPERATION_TIMEOUT){ + + } + } + + } + */ + }//eoc +}//eons \ No newline at end of file