MySQL服务器已经在delayed_job任务中消失了

And*_*ngh 10 delayed-job ruby-on-rails-3

我正在尝试调试一个场景,其中delayed_job进程因某些Mysql2::Error: MySQL server has gone away错误而在某些情况下死亡.

我的设置有点复杂,但我试图将其简化为基础知识.类中的run方法ClustalwFlowTask作为后台作业处理.它基本上运行一个clustalw2命令(一个为DNA和蛋白质进行多序列比对的程序)

命令的详细信息和执行期间发生的任何错误都应该记录在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
Run Code Online (Sandbox Code Playgroud)

当用户没有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
Run Code Online (Sandbox Code Playgroud)

这里似乎发生的事情是delayed_job试图从db中删除一个成功的任务,但由于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
Run Code Online (Sandbox Code Playgroud)

我已经没有关于如何调试它的想法,所以任何帮助将不胜感激.

bet*_*att 9

尝试添加reconnect: true到您的database.yml