Allow to increase the pdf generation timeout

The short version
Please allow to increase the PDF renderer timeout.
I would like to allow a certain time per page. For example, if I need to generate a 100 page PDF, I would like to be able to say PDFRenderer(timeout=56, ...) to allow half a second per page plus 6 seconds overhead.
A dedicated server account like mine could increase the timeout without affecting other users performances.

The long version
As I understand, the PDFRenderer uses a headless Chrome running on the Anvil server to render a form and print it to PDF. And, since that headless Chrome is a resource hog, it is killed after 30 seconds to prevent it from using all the server resources in case there is a bug that keeps the form open for too long. The app logs show that it takes about 6 seconds for that Chrome instance to startup, so the time left for the rendering is 24 seconds.

My forms are slow to render because they collect lots of data, crunch lots of numbers, show summaries, details and canvasses with graphic representations. When I need to print the content of a truck for example, the form uses expressions like these in the databinding repeating_panel.items = truck.crates, sub_repeating_panel.items = crate.panels. Some forms includes repeating panel forms with some graphics generated by methods like crate.draw_panels(). The full PDF includes several forms, in some cases more than 40. Multiple forms are concatenated by adding them to an empty form, one after the other separated by a PageBreak custom component (from Anvil Extras).

I optimized the forms by allowing them to optionally get the data as an argument, so they save the time to collect the data. This was fairly easy, because the data collected from the tables can easily be passed to a form argument.

Rendering 40 forms can take longer than one minute. Collecting all the data first and then rendering the forms, can still take longer than 24 seconds.

I did not optimize the data crunching and rendering parts, because making their result serializable would require an almost complete rewrite of the whole app. (And I wouldn’t know how to serialize an image drawn on a canvas.)

My solution will be to spin a PDFRenderer, generate a few pages, spin a second PDFRenderer, generate more pages, etc. At the end I will stitch all the pages together and finally serve the result.

Because of the multiple startup overheads, this solution will be more a resource hog than increasing the timeout.

5 Likes