生成带有图像的pdf时,PDFkit挂起 [英] PDFkit hangs when generating a pdf with an image

查看:115
本文介绍了生成带有图像的pdf时,PDFkit挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将网页呈现为PDF.它使用单个图像,并且我读到您需要提供PDFkit的绝对URL才能使用该图像,所以我的代码是:

I want to render a webpage as a PDF. It uses a single image, and I've read that you need to supply the absolute URL for PDFkit to be able to use the image, so my code is:

= image_tag image_url(user.avatar)

当以HTML格式查看时,此方法有效,并且PDFkit能够生成去除了图像的PDF.但是,使用映像时,它只是挂起,直到我杀死服务器为止.我怎样才能使它正常工作?

This works when viewed as HTML, and PDFkit is able to generate a PDF with the image removed. However, when using the image, it just hangs until I kill the server. How can I get this to work?

这是我杀死服务器时的完整输出:

Here's the full output when I kill the server:

2013-12-04 13:53:36.576 wkhtmltopdf[27410:507] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
2013-12-04 13:53:36.577 wkhtmltopdf[27410:507] CoreText performance note: Set a breakpoint on CTFontLogSuboptimalRequest to debug.
2013-12-04 13:53:36.582 wkhtmltopdf[27410:507] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
2013-12-04 13:53:36.584 wkhtmltopdf[27410:507] CoreText performance note: Client called CTFontCreateWithName() using name "Arial" and got font with PostScript name "ArialMT". For best performance, only use PostScript names when calling this API.
^C
RuntimeError - command failed: /usr/local/bin/wkhtmltopdf --page-size Legal --print-media-type --quiet - -:
  pdfkit (0.5.4) lib/pdfkit/pdfkit.rb:73:in `to_pdf'
  pdfkit (0.5.4) lib/pdfkit/middleware.rb:21:in `call'
  warden (1.2.3) lib/warden/manager.rb:35:in `block in call'
  warden (1.2.3) lib/warden/manager.rb:34:in `catch'
  warden (1.2.3) lib/warden/manager.rb:34:in `call'
  rack (1.5.2) lib/rack/etag.rb:23:in `call'
  rack (1.5.2) lib/rack/conditionalget.rb:25:in `call'
  rack (1.5.2) lib/rack/head.rb:11:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/params_parser.rb:27:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/flash.rb:241:in `call'
  rack (1.5.2) lib/rack/session/abstract/id.rb:225:in `context'
  rack (1.5.2) lib/rack/session/abstract/id.rb:220:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/cookies.rb:486:in `call'
  activerecord (4.0.0) lib/active_record/query_cache.rb:36:in `call'
  activerecord (4.0.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:626:in `call'
  activerecord (4.0.0) lib/active_record/migration.rb:369:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/callbacks.rb:29:in `block in call'
  activesupport (4.0.0) lib/active_support/callbacks.rb:373:in `_run__4124003592524659480__call__callbacks'
  activesupport (4.0.0) lib/active_support/callbacks.rb:80:in `run_callbacks'
  actionpack (4.0.0) lib/action_dispatch/middleware/callbacks.rb:27:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/reloader.rb:64:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/remote_ip.rb:76:in `call'
  better_errors (1.0.1) lib/better_errors/middleware.rb:84:in `protected_app_call'
  better_errors (1.0.1) lib/better_errors/middleware.rb:79:in `better_errors_call'
  better_errors (1.0.1) lib/better_errors/middleware.rb:56:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/debug_exceptions.rb:17:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/show_exceptions.rb:30:in `call'
  railties (4.0.0) lib/rails/rack/logger.rb:38:in `call_app'
  railties (4.0.0) lib/rails/rack/logger.rb:21:in `block in call'
  activesupport (4.0.0) lib/active_support/tagged_logging.rb:67:in `block in tagged'
  activesupport (4.0.0) lib/active_support/tagged_logging.rb:25:in `tagged'
  activesupport (4.0.0) lib/active_support/tagged_logging.rb:67:in `tagged'
  railties (4.0.0) lib/rails/rack/logger.rb:21:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/request_id.rb:21:in `call'
  rack (1.5.2) lib/rack/methodoverride.rb:21:in `call'
  rack (1.5.2) lib/rack/runtime.rb:17:in `call'
  activesupport (4.0.0) lib/active_support/cache/strategy/local_cache.rb:83:in `call'
  rack (1.5.2) lib/rack/lock.rb:17:in `call'
  actionpack (4.0.0) lib/action_dispatch/middleware/static.rb:64:in `call'
  railties (4.0.0) lib/rails/engine.rb:511:in `call'
  railties (4.0.0) lib/rails/application.rb:97:in `call'
  rack (1.5.2) lib/rack/content_length.rb:14:in `call'
  thin (1.6.0) lib/thin/connection.rb:82:in `block in pre_process'
  thin (1.6.0) lib/thin/connection.rb:80:in `catch'
  thin (1.6.0) lib/thin/connection.rb:80:in `pre_process'
  thin (1.6.0) lib/thin/connection.rb:55:in `process'
  thin (1.6.0) lib/thin/connection.rb:41:in `receive_data'
  eventmachine (1.0.3) lib/eventmachine.rb:187:in `run_machine'
  eventmachine (1.0.3) lib/eventmachine.rb:187:in `run'
  thin (1.6.0) lib/thin/backends/base.rb:73:in `start'
  thin (1.6.0) lib/thin/server.rb:162:in `start'
  rack (1.5.2) lib/rack/handler/thin.rb:16:in `run'
  rack (1.5.2) lib/rack/server.rb:264:in `start'
  railties (4.0.0) lib/rails/commands/server.rb:84:in `start'
  railties (4.0.0) lib/rails/commands.rb:78:in `block in <top (required)>'
  railties (4.0.0) lib/rails/commands.rb:73:in `tap'
  railties (4.0.0) lib/rails/commands.rb:73:in `<top (required)>'
  bin/rails:4:in `require'
  bin/rails:4:in `<main>'

推荐答案

这是一个臭名昭著的问题,由于您的HTML中可能具有相对链接的资产(例如图像,CSS,JS,字体,等),并且您的Web服务器一次只能处理一个请求/线程(如WEBrick).

This is a notorious issue, and you're running into it because your probably have relatively linked assets in your HTML (i.e. images, CSS, JS, fonts, etc), and your web server is only capable of handling one request/thread at a time (like WEBrick).

那会发生什么呢?当您请求其URL时,服务器开始生成PDF. PDFkit找到了链接的资产,因此它尝试从服务器上加载该资产,而该服务器恰好与运行PDFkit的服务器相同.但是,服务器的单线程已经在忙于运行PDFkit,因此它无法释放"以服务于请求的资产.总之,这是一个僵局– PDFkit正在同一台服务器上等待PDFkit完成处理的资产,以便可以将资产提供给PDFkit ...

So what happens? The server begins generating the PDF when you request its URL. PDFkit finds a linked asset, so it tries to load this asset from the server, which happens to be the same server that PDFkit is running on. However, the server's single thread is already busy running PDFkit, so it cannot "free up" to serve the requested asset. In conclusion, it's a deadlock -- PDFkit is awaiting on an asset on the same server that is waiting for PDFkit to finish up processing, so that it can serve the asset to PDFkit...

解决方案:

Solution: either Base64-embed your assets in the HTML so that PDFkit doesn't need to make any additional requests (my personally preferred solution), or temporarily offload the assets to another server (e.g. a temporary AWS bucket). You can also try using the unicorn or Thin webserver with multi-threading enabled, or adding config.threadsafe! in in application.rb, but there is no guarantee that these methods will work.

当然,这些黑客(将资产嵌入或托管在其他地方)仅应在开发环境中使用-您不应在生产中遇到此类问题,因为实时服务器应该(希望)能够处理多个GET请求.

Of course, these hacks (embedding assets or hosting elsewhere) should only be used in the dev environment -- you shouldn't be running into these kinds of issues in production, as the live server should (hopefully) be able to handle multiple GET requests.

这篇关于生成带有图像的pdf时,PDFkit挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆