Skip to content

Commit

Permalink
Even faster for postgresql
Browse files Browse the repository at this point in the history
  • Loading branch information
scosman committed Jan 29, 2013
1 parent 940bf92 commit 5de3205
Showing 1 changed file with 13 additions and 11 deletions.
24 changes: 13 additions & 11 deletions lib/delayed/backend/active_record.rb
Expand Up @@ -68,17 +68,19 @@ def self.reserve(worker, max_run_time = Worker.max_run_time)

now = self.db_time_now

# This works on any database and uses seperate queries to lock and return the job
# Databases like PostgreSQL and MySQL that support "SELECT .. FOR UPDATE" (ActiveRecord Pessimistic locking) don't need the second application
# of 'readyScope' but it doesn't hurt and it ensures that the job being locked still meets ready_to_run criteria.
count = readyScope.where(:id => nextScope).update_all(:locked_at => now, :locked_by => worker.name)
return nil if count == 0
return self.where(:locked_at => now, :locked_by => worker.name).first

# This works on PostgreSQL and uses 1 less query, but uses SQL not supported nativly through ActiveRecord
#quotedTableName = ::ActiveRecord::Base.connection.quote_column_name(self.table_name)
#reserved = self.find_by_sql(["UPDATE #{quotedTableName} SET locked_at = ?, locked_by = ? WHERE id IN (#{nextScope.to_sql}) RETURNING *",now,worker.name])
#return reserved[0]
if rails3? && (::ActiveRecord::Base.connection.adapter_name == "PostgreSQL")
# This works on PostgreSQL and uses 1 less query, but uses SQL not supported nativly through ActiveRecord
quotedTableName = ::ActiveRecord::Base.connection.quote_column_name(self.table_name)
reserved = self.find_by_sql(["UPDATE #{quotedTableName} SET locked_at = ?, locked_by = ? WHERE id IN (#{nextScope.to_sql}) RETURNING *",now,worker.name])
return reserved[0]
else
# This works on any database and uses seperate queries to lock and return the job
# Databases like PostgreSQL and MySQL that support "SELECT .. FOR UPDATE" (ActiveRecord Pessimistic locking) don't need the second application
# of 'readyScope' but it doesn't hurt and it ensures that the job being locked still meets ready_to_run criteria.
count = readyScope.where(:id => nextScope).update_all(:locked_at => now, :locked_by => worker.name)
return nil if count == 0
return self.where(:locked_at => now, :locked_by => worker.name).first
end
end

# Lock this job for this worker.
Expand Down

0 comments on commit 5de3205

Please sign in to comment.