2012-10-30 86 views
4

我正在尝试使用Ruby的daemon gem并循环重新启动具有自己的循环的守护进程。我的代码看起来像现在这样:如何循环重启守护进程?

require 'daemons' 

while true 
    listener = Daemons.call(:force => true) do 
    users = accounts.get_updated_user_list 

    TweetStream::Client.new.follow(users) do |status| 
     puts "#{status.text}" 
    end 
    end 
    sleep(60) 
    listener.restart 
end 

运行这给了我下面的错误(60秒后):

undefined method `restart' for #<Daemons::Application:0x007fc5b29f5658> (NoMethodError) 

所以很明显Daemons.call不返回一个可控的守护像我想它。我需要做什么才能正确设置它。守护进程是否是正确的工具?

+0

你的意图究竟是什么?我无法分辨你想做什么,但我可以猜测你走错了路。 为什么你想每60秒重新启动守护进程? – Fitzsimmons

+0

我正在使用Tweetstream gem从用户列表中获取Tweets。每分钟(或10分钟或其他),我想重新生成该用户列表,然后重新启动Tweetstream客户端。我将更新示例代码以更好地反映这一点。 – DorkRawk

回答

3

我认为这是你之后,虽然我没有测试过它。

class RestartingUserTracker 
    def initialize 
    @client = TweetStream::Client.new 
    end 

    def handle_status(status) 
    # do whatever it is you're going to do with the status 
    end 

    def fetch_users 
    accounts.get_updated_user_list 
    end 

    def restart 
    @client.stop_stream 
    users = fetch_users 
    @client.follow(users) do |status| 
     handle_status(status) 
    end 
    end 
end 

EM.run do 
    client = RestartingUserTracker.new 
    client.restart 

    EM::PeriodicTimer.new(60) do 
    client.restart 
    end 
end 

下面是它如何工作的:

TweetStream使用EventMachine的内部,作为轮询的方式API永远和处理响应。我可以看到为什么你可能感觉卡住了,因为通常的TweetStream API会永远阻止,并且无法让你在任何时候进行干预。但是,TweetStream确实允许您在同一事件循环中设置其他内容。在你的情况下,一个计时器。我在这里找到了关于如何做到的文档:https://github.com/intridea/tweetstream#removal-of-on_interval-callback

通过启动我们自己的EventMachine reactor,我们能够将自己的代码注入反应堆并使用TweetStream。在这种情况下,我们使用一个简单的计时器,每60秒重新启动客户端。

EventMachine是一个叫做反应堆模式的实现。如果你想完全理解和维护这些代码,它可以帮助你找到关于它的一些资源并获得充分的理解。反应堆模式非常强大,但起初可能难以掌握。

但是,这段代码应该让你开始。另外,我会考虑将RestartingUserTracker重命名为更适合的东西。

+0

这看起来非常好!看起来我应该更多地了解EventMachine。我会明天测试这个,然后结束这个问题。谢谢! – DorkRawk