0

在 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 命令以记录各种操作。

4

1 回答 1

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

在这里使用全局 $ 是一个坏主意,如果您使用的线程可能会访问它,那么它不是很干净。

于 2012-10-28T12:44:31.857 回答