0

Ruby EventMachine で PeriodicTimer を作成すると、非常に不正確で、ランダムに正しく動作しないように見えます。それを修正する方法があるかどうか、または間違った方法で使用する可能性があるかどうか疑問に思っています。

以下は例です。10 秒ごとにグローバル配列 (mysql ステートメントを含む) をプルし、mysql コマンドを実行する PeriodicTimer があります。そのように実行すると、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 に答える