Ruby Rest-Client:如何让它永不超时?

18

我正在尝试使用 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 

看起来没有任何原因导致这个操作超时。有人知道是否存在超时参数我没有正确设置吗?

谢谢

6个回答

22

2
RestClient::Request.execute(:method => :post, :url => @url, :timeout => 90000000) - Bill Gathen
1
将要发送的任何参数(我认为OP中的:file_param)放入:payload中:Request.execute(:method => :post, :url => @url, :timeout => 90000000, :payload => { :file_param => file_obj }) - WiseOldDuck

14

查看文档,你可以通过 RestClient.execute 的 timeout 参数传递 -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>}

6
看起来已经更新为 nil 而不是 -1。使用 -1 会记录一个警告(但似乎可以正常工作)。 - WiseOldDuck

4
我已经使用了以下代码,就像Richard指出的那样,它非常完美。
resource = RestClient::Resource.new "url", 
                                    :timeout => $TIMEOUT, 
                                    :open_timeout => $OPEN_TIMEOUT

response = resource.get  :params => { ..... }

4

我已经广泛使用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

3

我遇到了类似的问题。快速查看源代码后发现以下不友好的部分:

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

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


5
稍微深入了解后发现,虽然 getpost 等相关的便捷方法确实无法传递 :timeout:open_timeout 选项,但它们只是对 Request.execute 的简单包装,而后者可以接受这些选项。我的意见是,最好用调用 execute 方法来替换对这些包装方法的调用,而不是使用 monkey patch(指动态修改代码),这样更好。 - Tom Harrison

2

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接