非同期でバックグラウンドジョブを処理するResqueで、
Jobのロック制御を行うプラグイン、resque-lockをrailsで使う
resque-lock
https://github.com/defunkt/resque-lock
Gemfile
gem "resque-lock", "~> 1.1.0", :require => 'resque/plugins/lock'
Jobは、Resque::Plugins::Lockを継承するだけで、
ロック制御を行うようになる
app/models/lock_test_job.rb
class LockTestJob
extend Resque::Plugins::Lock
@queue = :default
# 実行する処理
def self.perform(seconds)
puts "sleep #{seconds} seconds"
sleep seconds
end
end
デフォルトでは、以下のように、クラス名と文字列化したパラメータで、
ユニークなキーを作成している。
このlockメソッドをオーバーライドして、ロック制御のキーを変更できる
lib/resque/plugins/lock.rb
def lock(*args)
"lock:#{name}-#{args.to_s}"
end
app/models/lock_test_job.rb
class LockTestJob
extend Resque::Plugins::Lock
@queue = :default
# 引数にかかわらず同時に1つのjobだけ実行されるようにする
# 引数はperformと同じものが渡される
def lock(seconds)
"lock-test-job"
end
# 実行する処理
def self.perform(seconds)
puts "sleep #{seconds} seconds"
sleep seconds
end
end
controllerからは以下のようにキューにいれる
app/controllers/b2b/resque_test_controller.rb
def resque_lock_test
Resque.enqueue(LockTestJob, 60)
end
redisにキーが存在しており、そのキーのタイムアウト時刻にまだなっていない場合には、
lockプラグインのbefore_enqueメソッドでfalseが返り、enqueが実行されない