Created
October 30, 2023 17:55
-
-
Save tcortega/227bfcf7e33a7565002d0b7332c0174d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[RegisterSingleton] | |
public class LabelEngine | |
{ | |
private readonly ILogger _logger; | |
private readonly Timer _timer; | |
private readonly AsyncReaderWriterLock _lock = new(); | |
private IBrowser _browser = null!; | |
private readonly string _browserPath; | |
public LabelEngine(ILogger logger, IOptions<LabelEngineOptions> options) | |
{ | |
_logger = logger; | |
_browserPath = options.Value.BrowserPath; | |
_timer = new Timer(RestartBrowser, null, TimeSpan.FromMinutes(20), TimeSpan.FromMinutes(20)); | |
} | |
public Task InitAsync() => StartBrowser(); | |
public async Task<LabelResult> GenerateLabel(LabelFieldsModel inputData, string templateFile) | |
{ | |
using (await _lock.ReaderLockAsync()) | |
{ | |
Guard.IsNotNullOrEmpty(templateFile, nameof(templateFile)); | |
var templatePath = FileManager.GetTemplatePath(templateFile); | |
if (!File.Exists(templatePath)) | |
{ | |
_logger.Error("Template file not found: {TemplatePath}", templatePath); | |
throw new FileNotFoundException($"Template file not found: {templatePath}"); | |
} | |
var content = await File.ReadAllTextAsync(templatePath); | |
var template = Template.ParseLiquid(content); | |
var result = await template.RenderAsync(inputData, member => member.Name); | |
if (result is null) | |
{ | |
throw new InvalidOperationException("An error happened when attempting to build the render the template."); | |
} | |
var labelId = Guid.NewGuid(); | |
using var htmlLabel = FileManager.CreateTempFileEntry("html", labelId); | |
await File.WriteAllTextAsync(htmlLabel.FilePath, result); | |
await using var page = await _browser.NewPageAsync(); | |
await page.GoToAsync($"file://{htmlLabel.FilePath}"); | |
var labelOutputPath = FileManager.GetLabelPath(labelId); | |
await page.PdfAsync(labelOutputPath, new() | |
{ | |
Format = PaperFormat.A4 | |
}); | |
return new() | |
{ | |
LabelId = labelId, TrackingNumber = inputData.TrackingNumber | |
}; | |
} | |
} | |
private async Task StartBrowser() | |
{ | |
var launchOptions = new LaunchOptions | |
{ | |
ExecutablePath = _browserPath, Headless = true, Args = new[] | |
{ | |
"--disable-gpu", "--no-sandbox", "--disable-software-rasterizer", "--disable-dev-shm-usage", "--disable-extensions", "--disable-background-networking", "--disable-sync", "--metrics-recording-only", "--disable-default-apps", "--mute-audio" | |
} | |
}; | |
_browser = await Puppeteer.LaunchAsync(launchOptions); | |
} | |
private async void RestartBrowser(object? state) | |
{ | |
using (await _lock.WriterLockAsync()) | |
{ | |
try | |
{ | |
await _browser.CloseAsync(); | |
await StartBrowser(); | |
} | |
catch (Exception ex) | |
{ | |
_logger.Error(ex, "Error restarting browser"); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://github.com/StephenCleary/AsyncEx
Nito.AsyncEx.Coordination more specifically.