Я пытаюсь отладить сценарий, в котором процесс delayed_job умирает при определенных обстоятельствах из-за ошибки Mysql2::Error: MySQL server has gone away
.
Мои настройки немного сложны, но я попытался свести их к основам. Метод run
в классе ClustalwFlowTask
обрабатывается как фоновое задание. В основном он запускает команду clustalw2
(программа, которая выполняет множественное выравнивание последовательностей для ДНК и белков)
Сведения о команде и обо всех ошибках, возникающих во время ее выполнения, должны регистрироваться в таблице flow_tasks и не отслеживаться delayed_job (см. Операторы update_attribute
).
require 'open3'
class ClustalwFlowTask < FlowTask
def run
# setup code ------
# fasta is a file object
cmd = "clustalw2 -INFILE=#{fasta.path}"
Rails.logger.info "[INFO #{Time.now}] #{self} running #{cmd}"
#update_attribute(:command, cmd)
raw_stdin, raw_stdout, raw_stderr = Open3.popen3(cmd)
Rails.logger.info "*********** RAW STDERR: #{raw_stderr} ************"
stdin, stdout, stderr = [raw_stdin, raw_stdout, raw_stderr].map do |io|
s = io.read.strip rescue nil
io.close
s
end
Rails.logger.info "*************** #{stderr} *******************"
unless stderr.blank?
Rails.logger.info "============ THERE IS AN ERROR ============"
#update_attribute(:error, stderr)
return false
end
# more code here -----
end
Странное поведение начинается, когда у пользователя не установлен двоичный файл clustalw2
, то есть если переменная stderr в методе не пуста. Обратите внимание, что во время отладки я раскомментировал все операторы update_attribute
из метода #run
, поэтому в MySQL нет явного участия. (Одна из моих первых догадок заключалась в том, что сообщение stderr слишком велико или содержит что-то, что приводит к закрытию сервера MySQL, но это не так)
Журнал delayed_job содержит следующее:
2012-03-26T09:19:25-0700: [Worker(delayed_job host:JadeDragon.local pid:8998)] ClustalwFlowTask failed with ActiveRecord::StatementInvalid: Mysql2::Error: closed MySQL connection: DELETE FROM `delayed_jobs` WHERE `delayed_jobs`.`id` = 107 - 0 failed attempts
Здесь, похоже, происходит то, что delayed_job попытался удалить успешное задание из БД, но не смог этого сделать, потому что соединение mysql было разорвано. Это происходит после оператора return false
в коде ClustalwFlowTask#run
, поскольку именно тогда, согласно delayed_job, задача успешно завершена.
Журнал разработки имеет следующее:
================ THERE IS AN ERROR ================
(0.5ms) BEGIN
Mysql2::Error: MySQL server has gone away: BEGIN
SQL (0.2ms) DELETE FROM `delayed_jobs` WHERE `delayed_jobs`.`id` = 110
Mysql2::Error: closed MySQL connection: DELETE FROM `delayed_jobs` WHERE `delayed_jobs`.`id` = 110
(0.1ms) ROLLBACK
Mysql2::Error: closed MySQL connection: ROLLBACK
(0.1ms) BEGIN
Mysql2::Error: closed MySQL connection: BEGIN
(0.1ms) ROLLBACK
Mysql2::Error: closed MySQL connection: ROLLBACK
closed MySQL connection
У меня заканчиваются идеи о том, как это отладить, поэтому любая помощь будет принята с благодарностью.