Skip to content

Commit

Permalink
Refactor PDF generation with ReportSheetCache
Browse files Browse the repository at this point in the history
* Pass a `CancellationToken` to `CreateReportSheetPdfChromium`.
* Enhanced `CreateReportSheetPdfChromium` to handle process timeouts using `Task.WhenAny` and `TimeSpan`, and to throw `OperationCanceledException` if the process exceeds the timeout.
* Minor comment adjustment and clarification of `ProtocolTimeout` in `GetPathToCacheFile`.
  • Loading branch information
axunonb committed Sep 25, 2024
1 parent 0aa0d1a commit d77aa1b
Showing 1 changed file with 14 additions and 18 deletions.
32 changes: 14 additions & 18 deletions League/Caching/ReportSheetCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ private static bool IsOutdated(string cacheFile, DateTime dataModifiedOn)
// Temporary file with HTML content - extension must be ".html"!
var htmlUri = await CreateHtmlFile(html, tempFolder, cancellationToken);

var pdfFile = await CreateReportSheetPdfChromium(tempFolder, htmlUri);
var pdfFile = await CreateReportSheetPdfChromium(tempFolder, htmlUri, cancellationToken);

var cacheFile = MovePdfToCache(pdfFile, matchId);

Expand Down Expand Up @@ -154,7 +154,7 @@ private string GetPathToCacheFile(long matchId)
{ "--no-sandbox", "--disable-gpu", "--disable-extensions", "--use-cmd-decoder=passthrough" },
ExecutablePath = _pathToChromium,
Timeout = 5000,
ProtocolTimeout = 10000 // default is 180,000
ProtocolTimeout = 10000 // default is 180,000 - used for page.PdfDataAsync
};
// Use Puppeteer as a wrapper for the browser, which can generate PDF from HTML
// Start command line arguments set by Puppeteer v20:
Expand All @@ -168,7 +168,6 @@ private string GetPathToCacheFile(long matchId)
var fullPath = GetPathToCacheFile(matchId);
try
{
// page.PdfDataAsync times out after 180,000ms (3 minutes)
var bytes = await page.PdfDataAsync(new PuppeteerSharp.PdfOptions
{ Scale = 1.0M, Format = PuppeteerSharp.Media.PaperFormat.A4 }).ConfigureAwait(false);

Expand All @@ -183,9 +182,10 @@ private string GetPathToCacheFile(long matchId)
return fullPath;
}

private async Task<string> CreateReportSheetPdfChromium(string tempFolder, string htmlUri)
private async Task<string> CreateReportSheetPdfChromium(string tempFolder, string htmlUri, CancellationToken cancellationToken)
{
// Temporary file for the PDF stream form Chromium
// Temporary file for the PDF stream from Chromium
// Note: non-existing file is handled in MovePdfToCache
var pdfFile = Path.Combine(tempFolder, Path.GetRandomFileName() + ".pdf");

// Run Chromium
Expand All @@ -196,25 +196,21 @@ private async Task<string> CreateReportSheetPdfChromium(string tempFolder, strin
{ CreateNoWindow = true, UseShellExecute = false };
var proc = System.Diagnostics.Process.Start(startInfo);

if (proc is null)
if (proc == null)
{
_logger.LogError("Process '{PathToChromium}' could not be started.", _pathToChromium);
return pdfFile;
}

const int timeout = 8000;
var timePassed = 0;
while (proc is { HasExited: false })
{
timePassed += 100;
await Task.Delay(100, default);
if (timePassed < timeout) continue;
var timeout = TimeSpan.FromMilliseconds(5000);
var processTask = proc.WaitForExitAsync(cancellationToken);

proc.Kill(true);
throw new OperationCanceledException($"Chromium timed out after {timeout}ms.");
}
await Task.WhenAny(processTask, Task.Delay(timeout, cancellationToken));

if (processTask.IsCompleted) return pdfFile;

// non-existing file is handled in MovePdfToCache
return pdfFile;
proc.Kill(true);
throw new OperationCanceledException($"Chromium timed out after {timeout.TotalMilliseconds}ms.");
}

private static async Task<string> CreateHtmlFile(string html, string tempFolder, CancellationToken cancellationToken)
Expand Down

0 comments on commit d77aa1b

Please sign in to comment.