anowell / wkhtmltopdf-rs

High-level Rust bindings for wkhtmltopdf
MIT License
75 stars 12 forks source link

Hangs with multiple threads #1

Closed anowell closed 8 years ago

anowell commented 8 years ago

Despite the lazy static mutex that ensure we only init wkhtmltopdf once (via PdfGlobal::new(), it turns out that we can't let separate threads calling into wkhtmltopdf as it seems to result in hanging/idling inside wkhtmltopdf. Seems to align with this upstream issue

For now, don't spin up threads. I'll be experimenting with a few options:

  1. have each PdfGlobal fork into its own process
  2. return a LockResult<Mutex<T>> to callers, requiring them to unlock it before conversion (probably requires refactoring so all wkhtmltopdf calls happen during the call to convert, also means non-threaded uses will unnecessarily init/deinit for every conversion)
  3. Provide a toplevel wkhtmltopdf::init() -> LockResult<Mutex<PdfBuilder>> to make it clearer that you can have multiple builders in the same process.
  4. Skip to wkhtmltopdf 0.13 (alpha) if it allows threaded usage
anowell commented 8 years ago

Actually, even a full deinit, re-init in a separate thread falls apart: QApplication was not created in the main() thread.

So I believe that strikes option 2, and the general idea behind option 3 is really only viable if we return something like Option<PdfBuilder> if the PdfBuilder is only returned on first call and PdfBuilder is !Sync, !Send and does not implement Clone.

anowell commented 8 years ago

I opted for a variation of #3, where the builder (or PdfGlobalSettings constructor) can return Error::AlreadyInitialized if another instance is still alive or Error:InitThreadMismatch if a previous instance was initialized on a different thread.

This still allows building abstractions that fork their own processes for parallel conversions (I could be convinced to add such abstraction to this library if someone makes a case for it). This implementation should be revisited once testing on 0.13 starts.

anowell commented 8 years ago

ugh.. burned again.. turns out, wkhtmltopdf is even pickier, you simply can't call wkhtmltopdf_init more than once per process... so wkhtmltopdf_deinit implies no more generating PDFs for the life of this process.

https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1890

mfwre commented 2 years ago

For anyone not wanting to use wkhtmltopdf 0.13 alpha and looking for a temporary, albeit terribly inefficient, solution the procspawn crate works.