fix orphan instances

This commit is contained in:
Adrian Zürcher
2025-12-29 17:15:52 +01:00
parent 5b20d4406c
commit 7fec8e1101
3 changed files with 31 additions and 16 deletions

View File

@@ -17,11 +17,12 @@ import (
// html to pdf converter structure for
type Converter struct {
chromePath string
ctx context.Context
cancel context.CancelFunc
allocCancel context.CancelFunc
progress func(progress int)
chromePath string
allocCtx context.Context
allocCancel context.CancelFunc // Cancels the whole Chrome process manager
browserCtx context.Context // The specific browser instance
browserCancel context.CancelFunc // Closes the browser
progress func(progress int)
}
// NewConverter starts a new converter instance with a chrome headless shell executable
@@ -43,9 +44,17 @@ func NewConverter(chromePath string) (*Converter, error) {
opts = append(opts, platformOptions())
var allocCtx context.Context
allocCtx, c.cancel = chromedp.NewExecAllocator(context.Background(), opts...)
c.ctx, c.allocCancel = chromedp.NewContext(allocCtx)
c.allocCtx, c.allocCancel = chromedp.NewExecAllocator(context.Background(), opts...)
c.browserCtx, c.browserCancel = chromedp.NewContext(c.allocCtx)
// 5. "Warm up" the browser to ensure the executable actually runs
// This catches "file not found" or permission errors immediately
err = chromedp.Run(c.browserCtx)
if err != nil {
c.Close() // Cleanup if start fails
return nil, fmt.Errorf("failed to start chrome: %w", err)
}
return c, nil
}
@@ -82,11 +91,11 @@ func (c *Converter) Convert(files ...models.File) error {
htmlURL.WriteString(filepath.ToSlash(absPath))
ctx, cancel := context.WithTimeout(c.ctx, 60*time.Second)
defer cancel()
taskCtx, taskCancel := chromedp.NewContext(c.browserCtx)
timeoutCtx, timeoutCancel := context.WithTimeout(taskCtx, 60*time.Second)
var pdfData []byte
err = chromedp.Run(ctx,
err = chromedp.Run(timeoutCtx,
chromedp.Navigate(htmlURL.String()),
chromedp.WaitReady("body", chromedp.ByQuery),
chromedp.ActionFunc(func(ctx context.Context) error {
@@ -103,24 +112,27 @@ func (c *Converter) Convert(files ...models.File) error {
}),
)
timeoutCancel()
taskCancel()
if err != nil {
c.cancel()
return err
}
// Save PDF to file
if err := os.WriteFile(f.Output, pdfData, 0644); err != nil {
c.cancel()
return err
}
}
c.cancel()
return nil
}
func (c *Converter) Close() {
if c.cancel != nil {
c.cancel()
// Close browser first, then allocator
if c.browserCancel != nil {
c.browserCancel()
}
if c.allocCancel != nil {
c.allocCancel()
}
}