Rails, DelayedJob: 子プロセスで gem の require に失敗する問題の解消法


class LongTask
def perform
system("/opt/bin/ruby /home/kuroda/foo.rb")
end
end

というクラス LongTask が定義されていて、これを


Delayed::Job.enqueue LongTask.new()

のようにして DelayedJob で実行するとします。Rails は /usr/local/bin/ruby (Ruby 1.9.3) で動いていて、/opt/bin/rubyRuby 1.8.7 です。

最初、foo.rb を次のように書いていました。


require 'rubygems'
require 'mysql'

(省略)

シェル上で /opt/bin/ruby /home/kuroda/foo.rb を実行するのは問題ないのですが、DelayedJob から実行すると mysql ライブラリが読み込めません。

そこで、まず mysql ライブラリのパスを調べました。


$ /opt/bin/gem which mysql
/opt/lib/ruby/gems/1.8/gems/mysql-2.8.1/lib/mysql.rb

そして、次のように書き換えてうまく動くようになりました。


$LOAD_PATH.clear
$LOAD_PATH
<< "/opt/lib/ruby/gems/1.8/gems/mysql-2.8.1/lib/"
require 'mysql'

(省略)

調べると、$LOAD_PATHにはRuby 1.9.3とRuby 1.8.7の両方のライブラリのパスが含まれていました。それが混乱を招いていると考え、$LOAD_PATHをクリアして、mysql ライブラリのパスを直接指定することにしました。