【问题标题】:ruby rest-client: make it never timeout?ruby rest-client:让它永远不会超时?
【发布时间】:2011-05-25 01:07:32
【问题描述】:

我正在尝试使用 ruby​​ rest-client 将大量图像上传到我正在编写的网站。我的代码如下所示:

RestClient.post url, :timeout => 90000000, :open_timeout => 90000000, :file_param => file_obj

但是,我收到了这个错误:

RestClient::RequestTimeout: Request Timeout
    from /Library/Ruby/Gems/1.8/gems/rest-client-1.6.1/lib/restclient/request.rb:174:in `transmit'
    from /Library/Ruby/

但是当我查看服务器日志时

Completed in 61493ms (View: 2, DB: 1) | 201 Created 

因此,似乎没有任何原因导致超时。任何人都知道是否有我没有正确设置的超时参数?

谢谢

【问题讨论】:

    标签: ruby-on-rails rest-client


    【解决方案1】:

    我也有类似的问题。快速深入了解源代码会发现这种不友好:

    def self.post(url, payload, headers={}, &block)
      Request.execute(:method => :post, :url => url, :payload => payload, :headers => headers, &block)
    end
    

    除非我遗漏了什么,否则超时选项不会传递给底层请求。是时候打补丁了...

    【讨论】:

    • 更深入的研究表明,虽然getpost 和相关的便捷方法确实不允许您传递:timeout:open_timout 选项,但它们只是用于Request.execute,它将接受它们。最好用调用 execute 代替对包装器的调用,而不是猴子补丁,恕我直言。
    【解决方案2】:

    此语法将超时设置为请求标头(请参阅 RestClient.post 签名),如果要使用超时参数,则必须使用:

    RestClient::Request.execute(:method => :post, :url => @url, :timeout => 90000000)
    

    见:https://github.com/rest-client/rest-client/blob/master/lib/restclient/request.rb#L12

    【讨论】:

    • RestClient::Request.execute(:method => :post, :url => @url, :timeout => 90000000)
    • 并将要在POST正文中发送的任何参数(我认为OP中的:file_param)放入:payloadRequest.execute(:method => :post, :url => @url, :timeout => 90000000, :payload => { :file_param => file_obj })
    【解决方案3】:

    当您使用资源的 get、post、put 等方法时,RestClient::Resource.new() 允许您设置将传递给 Request.execute 方法的 :timeout 和 :open_timeout 值

    【讨论】:

      【解决方案4】:

      我使用了以下代码,就像理查德指出的那样具有魅力

      resource = RestClient::Resource.new "url", 
                                          :timeout => $TIMEOUT, 
                                          :open_timeout => $OPEN_TIMEOUT
      
      response = resource.get  :params => { ..... }
      

      【讨论】:

        【解决方案5】:

        查看文档,您可以通过 RestClient.execute 超时参数传递 -1:

        # * :timeout and :open_timeout passing in -1 will disable the timeout by setting the corresponding net timeout values to nil
        

        可以这样使用:

        resource = RestClient::Resource.new(
          "url",
          :timeout => -1,
          :open_timeout => -1
        response = resource.get :params => {<params>}
        

        【讨论】:

        • 这似乎已更新为 nil 而不是 -1。使用 -1 会记录一个警告(但似乎有效)。
        【解决方案6】:

        我已经广泛使用 RestClient.get 和 RestClient.post,所以对我来说,'Monkey Patch' RestClient 更容易。如果可能,我建议使用RestClient::Resource.newRestClient::Request.Execute

        但是,由于我很懒惰,并且不想在我的代码中替换所有出现的 RestClient.get / RestClient.post,所以我决定走捷径。

        $timeout = 30
        $open_timeout = 30
        
        module RestClient2
          include RestClient
        
          def self.get(url, headers={}, &block)
            Request.execute(:method => :get, :url => url, :headers => headers, 
             :timeout => $timeout, :open_timeout => $open_timeout, &block)
          end
        
          def self.post(url, payload, headers={}, &block)
            Request.execute(:method => :post, :url => url, :payload => payload, :headers => headers,
             :timeout => $timeout, :open_timeout => $open_timeout, &block)
          end
        end
        

        我只是快速将 RestClient.get/post 替换为 RestClient2.get/post。

        如果RestClient::Request 指定了默认超时,那就太好了,例如:

          @timeout = args[:timeout] || 30
          @open_timeout = args[:open_timeout] || 30
        

        【讨论】:

          猜你喜欢
          • 2017-01-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-22
          • 2013-10-16
          • 1970-01-01
          相关资源
          最近更新 更多