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/ruby は Ruby 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 ライブラリのパスを直接指定することにしました。