如何判断方法或循环是否已完成?

时间:2012-01-29 13:44:34

标签: ruby

我正在编写一个关于aRuby程序的奇怪问题。

基本上,这个想法是让程序在后台持续运行。该程序每30秒检查一次我的浏览器历史记录,并将任何新的历史记录项上传到服务器。

# client.rb
history = HistoryUploader.new(Chrome)
# Run everything
loop do
  history.run
  sleep 30
end

HistoryUploader类的重要部分如下所示

class HistoryUploader
  def run
    upload_history until local.last_seen_history_item == server.last_seen_history_item
  end

  def upload_history
    # POST batches of history items to the server
  end
end

我在这段代码中看到的主要问题是,如果HistoryUploader.run完成时间超过30秒(因为它发送了多个http请求,很可能就是这样),client.rb中的外部循环将尝试再次调用run,我可以获得并行请求进入服务器,这将真正混淆事情。

有没有办法可以阻止run方法被调用两次直到它完成?

2 个答案:

答案 0 :(得分:3)

我认为你没有自己认为的问题。您描述代码的方式仍然是单线程的。您没有启动新线程来执行history.run,这意味着在您的history.run方法返回之前不会执行sleep 30。

是否需要创建此线程取决于您要查找的行为。如果您想在history.run完成后30秒触发另一次对history.run的调用,您的代码将立即执行此操作。如果你想每隔30秒独立于history.run的执行时间运行它(例如,history.run需要7.5秒,所以你想在22.5秒内再次运行查询),那么线程解决方案可能是最多的优雅。

答案 1 :(得分:2)

我会使用一个接一个地执行请求的请求队列。您还可以在HistoryUploader中放置一个简单的布尔标志,例如@is_uploading:

class HistoryUploader

  attr_accessor :is_uploading

  def initialize
    @is_uploading = false
  end

  def run
    if @is_uploading
        return
    end     
    upload_history until local.last_seen_history_item == server.last_seen_history_item
  end

  def upload_history
    @is_uploading = true
    # POST batches of history items to the server
    # On uploading finished: 
    @is_uploading = false
  end
end

如果你真的想要阻止主循环,直到上传完成,你可以派遣一个线程并等待它完成使用join:

require 'thread'

t = Thread.new do
    #post to server
end
t.join