Ruby on rails 构造轮询外部服务(RoR)的最佳方法
我有一个Rails应用程序,它有一个Ruby on rails 构造轮询外部服务(RoR)的最佳方法,ruby-on-rails,ruby,polling,Ruby On Rails,Ruby,Polling,我有一个Rails应用程序,它有一个文档,标记为可用。文档将上载到外部服务器,但该服务器无法立即使用(传播需要时间)。我想做的是调查可用性,并在可用时更新模型 我正在为此过程寻找性能最好的解决方案(服务不提供回调): 文档已上载到应用程序 应用程序上载到外部服务器 应用程序轮询url(),直到可用为止 app updates model Document.available=true 我被困在3号线上了。我已经在我的项目中使用了sidekiq。这是一个选项,还是我应该使用完全不同的方法(cron
文档
,标记为可用
。文档将上载到外部服务器,但该服务器无法立即使用(传播需要时间)。我想做的是调查可用性,并在可用时更新模型
我正在为此过程寻找性能最好的解决方案(服务不提供回调):
文档
已上载到应用程序文档将一直上载,因此首先轮询数据库/redis以检查不可用的文档似乎是相关的。请参阅以下答案:
基本上,您为已知url设置一个HEAD请求,然后异步循环,直到返回200(迭代之间有5秒的延迟,或者其他)
上载文档后,从控制器执行此操作:
Document.delay.poll_for_finished(@document.id)
然后在文档模型中:
def self.poll_for_finished(document_id)
document = Document.find(document_id)
# make sure the document exists and should be polled for
return unless document.continue_polling?
if document.remote_document_exists?
document.available = true
else
document.poll_attempts += 1 # assumes you care how many times you've checked, could be ignored.
Document.delay_for(5.seconds).poll_for_finished(document.id)
end
document.save
end
def continue_polling?
# this can be more or less sophisticated
return !document.available || document.poll_attempts < 5
end
def remote_document_exists?
Net::HTTP.start('http://external.server.com') do |http|
http.open_timeout = 2
http.read_timeout = 2
return "200" == http.head(document.path).code
end
end
def self.poll_for_finished(文档id)
document=document.find(document\u id)
#确保该文档存在,并应轮询以获取
除非返回文档,否则返回。是否继续轮询?
如果document.remote\u document\u存在?
document.available=true
其他的
document.poll_尝试次数+=1#假设您关心检查了多少次,则可以忽略。
Document.delay_为(5.秒)。poll_为_完成(Document.id)
结束
document.save
结束
def是否继续轮询?
#这可能或多或少有些复杂
回来!document.available | | document.poll_尝试次数<5次
结束
def远程文档是否存在?
Net::HTTP.start('http://external.server.com“)do | http|
http.open\u超时=2
http.read_timeout=2
返回“200”==http.head(document.path).code
结束
结束
这仍然是一个阻塞操作。如果您试图联系的服务器速度慢或无响应,则打开Net::HTTP连接将被阻止。如果你担心的话,就用Typhous。请参阅此答案了解详细信息:这似乎是对Sidekiq工人的浪费。如果响应不是200,则最好使作业失败,然后稍后重试作业(例如,一分钟后)。工人可以快速前进并尝试其他文件。@davidcelis:我根据您的反馈更新了我的答案。进一步的改进可能包括缩短超时时间或切换到Tyohoeus,同时分批进行几次检查。