Ruby EventMachine PeriodicTimer хаос

Когато създавате PeriodicTimer в Ruby EventMachine, той е много неточен и изглежда действа произволно и неправилно. Чудя се дали има начин да го поправя или може би го използвам по грешен начин.

По-долу е даден пример. Имам 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 команди, за да регистрира различни действия.


person John Meyer    schedule 26.10.2012    source източник


Отговори (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

Използването на глобален $ е лоша идея тук, не е съвсем чисто, ако използвате нишки, които могат да имат достъп до него или не.

person phil pirozhkov    schedule 28.10.2012