ActiveResource超时无法正常工作

时间:2009-07-16 06:02:48

标签: ruby-on-rails ruby timeout

我正在尝试使用Rails 2.3.2上的ActiveResource联系REST API。

我正在尝试使用超时功能,以便如果我正在联系的资源停止运行,我可能会很快失败 - 我正在执行以下操作:

class WorkspaceResource < ActiveResource::Base
  self.timeout = 5
  self.site = "http://mysite.com/restAPI"
end

但是,当我知道它不可用时我尝试联系该服务时,该类仅在默认的60秒后超时。我可以从错误堆栈中看到,超时错误确实来自我的gem文件夹中的ActiveResource类,它具有允许超时设置的正确功能,但我的设置超时似乎永远不会起作用。

有什么想法吗?


显然问题不在于超时不起作用。我可以在本地运行服务器,使其不在超时限制内返回响应,并查看超时是否有效。

问题实际上是,如果服务器不接受连接,超时不会像我预期的那样起作用 - 它根本不起作用。似乎超时只在服务器接受连接时才起作用,但响应时间太长。

对我来说,这似乎是一个问题 - 当我正在联系的服务器关闭时,不应该超时吗?如果没有,应该有另一种机制来阻止一堆请求挂起......任何人都知道快速的方法吗?

3 个答案:

答案 0 :(得分:1)

实际上我自己找到了答案,在另一个帖子中讨论:

Overriding/Modifying Rails Class (ActiveResource)

答案 1 :(得分:0)

问题

如果你在Ruby 1.8.x上运行,那么问题是它缺乏真正的系统线程。

正如您可以阅读first herethen here,Ruby中存在超时的系统性问题。一个有趣的讨论,但对你特别是一些评论表明超时被有效忽略,默认为60秒 - 正是你所看到的。


解决方案......

我在尝试发送电子邮件时遇到与我们自己的产品类似的问题 - 如果电子邮件服务器在线程块中出现问题。对我来说,解决方案是在一个单独的线程上关闭请求,因此我的主请求处理线程不会阻塞。

Ruby有非阻塞库,但也许您可以先看看System Timeout Gem

对任何在nginx之类的代理后面使用Rails的人开放的选项是将上游超时设置为较低的数字 - 这样,如果服务器花费的时间过长,您将收到通知。如果我真的被困在一个解决方案中,我只会这样做。

最后但并非最不重要的是,在Ruby 1.9.1之上运行Rails 2.3.2可能会解决问题。

答案 2 :(得分:0)

或者,您可以尝试捕获这些连接错误并重试一次(在一段时间之后),以确保连接真的不存在。

      retried = false
      begin
        @businesses = Business.find(:all, :params => { :shop_domain => @shop.domain })
        retried = false
      rescue ActiveResource::TimeoutError => ex          

      #raise ex

      rescue ActiveResource::ConnectionError, ActiveResource::ServerError, ActiveResource::ClientError => ex
        unless retried           
          sleep(((ex.respond_to?(:response) && ex.response['Retry-After']) || 5).to_i)
          retried = true             
          retry
        else              
          # raise ex
        end
      end

受Shopify解决方案的启发,对大量记录进行分页。 https://ecommerce.shopify.com/c/shopify-apis-and-technology/t/paginate-api-results-113066