4

我正在尝试使用 Ruby 的daemongem 并循环重启具有自己循环的守护程序。我的代码现在看起来像这样:

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不会像我想的那样返回一个可控的守护进程。我需要做什么才能正确设置它。守护进程在这里是正确的工具吗?

4

1 回答 1

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 uses EventMachine internally, as a way of polling the API forever and handling the responses. I can see why you might have felt stuck, because the normal TweetStream API blocks forever and doesn't give you a way to intervene at any point. However, TweetStream does allow you to set up other things in the same event loop. In your case, a timer. I found the documentation on how to do that here: https://github.com/intridea/tweetstream#removal-of-on_interval-callback

By starting up our own EventMachine reactor, we're able to inject our own code into the reactor as well as use TweetStream. In this case, we're using a simple timer that just restarts the client every 60 seconds.

EventMachine is an implementation of something called the Reactor Pattern. If you want to fully understand and maintain this code, it would serve you well to find some resources about it and gain a full understanding. The reactor pattern is very powerful, but can be difficult to grasp at first.

However, this code should get you started. Also, I'd consider renaming the RestartingUserTracker to something more appropriate.

于 2012-11-01T21:33:13.953 回答