2012-01-29 78 views
2

我正在写一个Ruby程序,我有一个奇怪的问题。如何判断方法或循环是否完成?

基本上这个想法是让程序在后台不断运行。该程序每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

我会使用一个接一个地执行请求的请求队列。您还可以在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 

如果你真的想,直到上传完成后,你可以派遣一个线程并等待它完成使用挡主循环连接:

require 'thread' 

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

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

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

相关问题