Fel*_*vni 3 ruby-on-rails delayed-job
当delay_job从队列中拉出新作业时,它是否首先按优先级对队列进行排序?如果没有,那么我猜因为“ read_ahead”,低优先级的作业可以先于高优先级运行。
从delay_job文档中:
默认行为是在找到可用作业时从队列中读取5个作业。您可以通过设置Delayed :: Worker.read_ahead来配置它。
示例:我添加了100个优先级为10的作业(优先级较低的优先级首先运行)。然后,我添加1个优先级为0的作业。如果我使用默认的read_ahead值为5,则delay_job是否需要首先处理96个作业,然后才能找到我的一个高优先级作业?
小智 5
我有一个类似的问题,并在源代码中找到了答案-这是假设您正在使用delayed_job_active_record。在backend / active_record.rb中:
class Job < ::ActiveRecord::Base
scope :by_priority, lambda { order("priority ASC, run_at ASC") }
def self.reserve(worker, max_run_time = Worker.max_run_time) # rubocop:disable CyclomaticComplexity
# scope to filter to records that are "ready to run"
ready_scope = ready_to_run(worker.name, max_run_time)
# scope to filter to the single next eligible job
ready_scope = ready_scope.where("priority >= ?", Worker.min_priority) if Worker.min_priority
ready_scope = ready_scope.where("priority <= ?", Worker.max_priority) if Worker.max_priority
ready_scope = ready_scope.where(queue: Worker.queues) if Worker.queues.any?
ready_scope = ready_scope.by_priority
reserve_with_scope(ready_scope, worker, db_time_now)
end
def self.reserve_with_scope(ready_scope, worker, now)
# Optimizations for faster lookups on some common databases
case connection.adapter_name
when "PostgreSQL"
quoted_table_name = connection.quote_table_name(table_name)
subquery_sql = ready_scope.limit(1).lock(true).select("id").to_sql
reserved = find_by_sql(["UPDATE #{quoted_table_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery_sql}) RETURNING *", now, worker.name])
reserved[0]
when "MySQL", "Mysql2"
now = now.change(usec: 0)
count = ready_scope.limit(1).update_all(locked_at: now, locked_by: worker.name)
return nil if count == 0
where(locked_at: now, locked_by: worker.name, failed_at: nil).first
when "MSSQL", "Teradata"
subsubquery_sql = ready_scope.limit(1).to_sql
subquery_sql = "SELECT id FROM (#{subsubquery_sql}) AS x"
quoted_table_name = connection.quote_table_name(table_name)
sql = ["UPDATE #{quoted_table_name} SET locked_at = ?, locked_by = ? WHERE id IN (#{subquery_sql})", now, worker.name]
count = connection.execute(sanitize_sql(sql))
return nil if count == 0
where(locked_at: now, locked_by: worker.name, failed_at: nil).first
else
reserve_with_scope_using_default_sql(ready_scope, worker, now)
end
end
def self.reserve_with_scope_using_default_sql(ready_scope, worker, now)
# This is our old fashion, tried and true, but slower lookup
ready_scope.limit(worker.read_ahead).detect do |job|
count = ready_scope.where(id: job.id).update_all(locked_at: now, locked_by: worker.name)
count == 1 && job.reload
end
end
Run Code Online (Sandbox Code Playgroud)
因此,看起来优先级具有优先权-当DelayedJob查找要保留和运行的下一个可用作业时,它先按优先级进行排序,然后再尝试将结果限制为“ read_ahead”。
实际上,最后一个方法reserve_with_scope_using_default_sql甚至是唯一提到“ read_ahead”的地方,因此,如果您使用的是Postgres或MySQL,它会自动选择优先级最高的作业(限制1),而忽略“ read_ahead”。
| 归档时间: |
|
| 查看次数: |
477 次 |
| 最近记录: |