【问题标题】:Why is Net::HTTP timing out when I try to access a Prawn Generated PDF?为什么当我尝试访问 Prawn Generated PDF 时 Net::HTTP 超时?
【发布时间】:2011-12-14 19:42:18
【问题描述】:

我正在使用 Prawn 从我的控制器生成 PDF,当直接通过 url 访问时,它可以完美运行,即 I.E.本地主机:3000/responses/1.pdf

但是,当我尝试动态生成此文件以包含在 Mailer 中时,一切都冻结并超时。

我尝试了各种生成/附加文件的方法,但都没有改变结果。

我也尝试过修改 Net::HTTP 的超时时间,但无济于事,超时时间更长。

如果我在 Rails 控制台上运行此命令,我会收到一个 PDF 数据流。

Net::HTTP.get('127.0.0.1',"/responses/1.pdf", 3000)

但如果我在控制器中包含此代码,则会超时。

我尝试了两种不同的方法,但都反复失败。

方法一 控制器:

http = Net::HTTP.new('localhost', 3000)
http.read_timeout = 6000
file = http.get(response_path(@response, :format => 'pdf')) #timeout here
ResponseMailer.confirmComplete(@response,file).deliver #deliver the mail!

方法 1 邮件:

def confirmComplete(response,file)
  email_address = response.supervisor_id
  attachments["test.pdf"] = {:mime_type => "application/pdf", :content=> file}
  mail to: email_address, subject: 'Thank you for your feedback!'
end

以上代码超时。

方法 2 控制器:

ResponseMailer.confirmComplete(@response).deliver #deliver the mail!

方法 2 邮件:

def confirmComplete(response)
email_address = response.supervisor_id
attachment "application/pdf" do |a|
    a.body = Net::HTTP.get('127.0.0.1',"/responses/1.pdf", 3000) #timeout here
    a.filename = "test.pdf" 
end
mail to: email_address, subject: 'Thank you for your feedback!'

结束

如果我切换 a.body 和 a.filename,它首先会出错

undefined method `filename=' for #<Mail::Part:0x007ff620e05678>

我找到的每个示例都有不同的语法或建议,但没有一个可以解决 Net::HTTP 超时的问题。 Rails 3.1、Ruby 1.9.2

【问题讨论】:

  • 您是否尝试使用curlwget 获取该pdf url?
  • Wget 也卡住了Resolving localhost... 127.0.0.1 Connecting to localhost|127.0.0.1|:3000... connected. HTTP request sent, awaiting response... 并挂在那里。不过,同样的命令也可以在命令行上运行。
  • Web Server 似乎有奇怪的问题,尝试使用另一个,f.ex。如果您目前使用 WEBrick,请尝试与 Mongrel 或Passenger 确认

标签: ruby pdf ruby-on-rails-3.1 prawn net-http


【解决方案1】:

问题在于,在开发过程中,您只运行一个服务器进程,它正忙于生成电子邮件。该过程正在发送另一个请求(向自身)以生成 PDF 并等待响应。对 PDF 的请求基本上在服务器上排队,以便它可以获取它的 PDF,但服务器正忙于生成电子邮件并等待获取 PDF 才能完成。因此,您将永远等待。

您需要做的是启动第二个服务器进程...

script/rails server -p 3001

然后使用类似...的内容获取您的 PDF

args = ['127.0.0.1','/responses/1.pdf']
args << 3001 unless Rails.env == 'production'
file = Net::HTTP.get(*args)

顺便说一句,根据您在生产机器上运行的服务器,您可能会遇到指向 127.0.0.1 的问题。在生产环境中,您可能需要使其动态化并指向整个域,但这应该很容易。

【讨论】:

    【解决方案2】:

    我同意https://stackoverflow.com/users/811172/jon-garvin 的分析,即您只运行一个服务器进程,但我会提到另一种解决方案。重构您的 PDF 生成,以便您不依赖于您的控制器。

    如果您使用的是Prawnto,我猜您的视图类似于

    # app/views/response.pdf.prawn
    pdf.text "Hello world"
    

    将此移至您的 Response 模型:(或其他更合适的位置,例如演示者)

    # app/models/response.rb
    require 'tmpdir'
    class Response < ActiveRecord::Base
      def pdf_path
        return @pdf_path if @pdf_generated == true
        @pdf_path = File.join(Dir.tmpdir, rand(1e11).to_s)
        Prawn::Document.generate(@pdf_path) do |pdf|
          pdf.text "Hello world"
        end
        @pdf_generated = true
        @pdf_path
      end
    
      def pdf_cleanup
        if @pdf_generated and File.exist?(@pdf_path.to_s)
          File.unlink @pdf_path
        end
      end
    end
    

    然后在你的ResponsesController 你可以这样做:

    # app/controllers/responses_controller.rb
    def show
      @response = Response.find params[:id]
      respond_to do |format|
        # this sends the PDF to the browser (doesn't email it)
        format.pdf { send_file @response.pdf_path, :type => 'application/pdf', :disposition => 'attachment', :filename => 'test.pdf' }
      end
    end
    

    您可以在邮件中执行以下操作:

    # this sends an email with the PDF attached
    def confirm_complete(response)
      email_address = response.supervisor_id
      attachments['test.pdf'] = {:mime_type => "application/pdf", :content => File.read(response.pdf_path, :binmode => true) }
      mail to: email_address, subject: 'Thank you for your feedback!'
    end
    

    由于您在 tmpdir 中创建了它,因此在您的服务器重新启动时它会被自动删除。也可以调用清理函数。

    最后一点:您可能想要使用不同的模型名称,例如 SupervisorReport 或其他名称 - Response 可能会在以后给您带来命名空间问题)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-17
      • 1970-01-01
      • 2022-09-28
      • 1970-01-01
      • 2014-06-06
      • 2015-12-07
      相关资源
      最近更新 更多