diff --git a/lib/delayed/backend/active_record.rb b/lib/delayed/backend/active_record.rb index 64f36953..ef39d5c0 100644 --- a/lib/delayed/backend/active_record.rb +++ b/lib/delayed/backend/active_record.rb @@ -60,9 +60,10 @@ def self.find_available(worker_name, limit = 5, max_run_time = Worker.max_run_ti scope = scope.scoped(:conditions => ['priority >= ?', Worker.min_priority]) if Worker.min_priority scope = scope.scoped(:conditions => ['priority <= ?', Worker.max_priority]) if Worker.max_priority scope = scope.scoped(:conditions => ["queue IN (?)", Worker.queues]) if Worker.queues.any? + scope = scope.scoped(:conditions => ["queue NOT IN (?)", Worker.not_queues]) if Worker.not_queues.any? ::ActiveRecord::Base.silence do - scope.by_priority.all(:limit => limit) + scope.by_priority.all(:limit => limit).shuffle end end @@ -72,7 +73,15 @@ def lock_exclusively!(max_run_time, worker) now = self.class.db_time_now affected_rows = if locked_by != worker # We don't own this job so we will update the locked_by name and the locked_at - self.class.update_all(["locked_at = ?, locked_by = ?", now, worker], ["id = ? and (locked_at is null or locked_at < ?) and (run_at <= ?)", id, (now - max_run_time.to_i), now]) + begin + self.class.update_all(["locked_at = ?, locked_by = ?", now, worker], ["id = ? and (locked_at is null or locked_at < ?) and (run_at <= ?)", id, (now - max_run_time.to_i), now]) + rescue Exception => e + if e.message =~ /Deadlock found when trying to get lock/ + 0 + else + raise e + end + end else # We already own this job, this may happen if the job queue crashes. # Simply resume and update the locked_at