在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命令来记录各种操作。
答案 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
在这里使用全局$是一个坏主意,如果你使用可能访问它的线程,它就不太干净了。