Ruby EventMachine PeriodicTimer混乱

时间:2012-10-26 11:42:02

标签: ruby eventmachine

在Ruby EventMachine中创建PeriodicTimer时,它非常不准确,似乎随机且不正确。 我想知道是否有办法解决这个问题,或者我是否可能以错误的方式使用它。

以下是一个例子。 我有一个PeriodicTimer,每隔10秒就会拉一个全局数组(包含mysql语句)并执行mysql命令。 当像这样运行它时,PeriodicTimer最终可能每隔几分钟才会这样做,或者它会在一段时间后完全停止,以及其他奇特的异常。

Eventmachine::run {

  EM::PeriodicTimer.new(10) {
    mysql_queue = $mysql_queue.dup
    $mysql_queue = []
    mysql_queue.each do |command|
      begin
        Mysql.query(command)
      rescue Exception => e
        puts "Error occured.. #{e} #{command}"
      end
    end
  }

  # Here follow random tasks/loops that are adding mysql statements to $mysql_queue
  100_000.times {
    if ...
      $mysql_queue << "INSERT INTO `...` (...) VALUES (...);"
    end
  }
  ...
  # ...

}

如果你想知道,我喜欢使用这样的“Mysql队列”,因为它可以防止竞争条件。 实际上,这实际上是一个小型TCP / IP客户端,它处理多个并发连接并执行mysql命令来记录各种操作。

1 个答案:

答案 0 :(得分:1)

您希望此代码能做什么?如果你没有将控制传递给EM循环,为什么你认为定时器会被调用? 尝试将100_000循环拆分为较小的部分:

10_000.times do
  EM.next_tick do
    10.times do
      if ...
        $mysql_queue << "INSERT INTO `...` (...) VALUES (...);"
      end
    end
  end
end

在这里使用全局$是一个坏主意,如果你使用可能访问它的线程,它就不太干净了。