如果您在https://github.com/collatectiveidea/delayed_job上查看此信息,则您正在阅读Master Branch的文档。查看最新版本的文档(4.1.13)。
延迟:: job(或DJ)封装了在后台执行较长任务的常见模式。
这是从Shopify的直接提取,在该工作表负责多项核心任务。这些任务包括:
发送大量新闻通讯
图像调整大小
HTTP下载
更新智能收藏
更新产品后更新Solr,我们的搜索服务器
批量导入
垃圾邮件检查
在Twitter上关注我们,以获取有关新版本的更新和通知。
delayed_job 3.0.0仅支持导轨3.0+。
delayed_job支持多个存储工作队列的后端。有关其他后端,请参见Wiki。
如果您打算将delayed_job与活动记录一起使用,请将delayed_job_active_record
添加到您的Gemfile
中。
宝石'delayed_job_active_record'
如果您打算将delayed_job与mongoid一起使用,请将delayed_job_mongoid
添加到您的Gemfile
中。
宝石'delayed_job_mongoid'
运行bundle install
以安装后端并延迟_job宝石。
主动记录后端需要一个工作表。您可以通过运行以下命令来创建该表:
rails generate delayed_job:active_record rake db:migrate
对于4.2+的铁路,请参见下文
在开发模式下,如果您使用的是Rails 3.1+,则您的应用程序代码将每100个作业或队列完成时自动重新加载。每次更新开发代码时,您都不再需要重新启动延迟作业。
在Rails 4.2+中,将Queue_Adapter设置为config/application.rb
config.active_job.queue_adapter =:delayed_job
有关更多详细信息,请参见《铁路指南》。
如果您使用的是protected_attributes GEM,则必须在delayed_job中出现在您的gemfile中。如果您的工作失败:
ActiveRecord::StatementInvalid: PG::NotNullViolation: ERROR: null value in column "handler" violates not-null constraint
然后,这是您要寻找的修复程序。
延迟作业3.0.0向delayed_jobs表介绍了一个新列。
如果您要从延迟的作业2.x升级,请运行升级生成器以创建迁移以添加列。
rails generate delayed_job:upgrade rake db:migrate
在任何对象上调用.delay.method(params)
并且将在后台处理。
#毫不[email protected]!(@device)#[email protected]!(@device)
如果应始终在后台运行方法,则可以在方法声明之后调用#handle_asynchronously
:
类设备 def交付#长运行方法 结尾 hander_asynchronicaly:deliverenddevice = device.newdevice.deliver
#handle_asynchronously
和#delay
采用以下参数:
:priority
(数字):较低的数字首先运行;默认值为0,但可以重新配置(请参见下文)
:run_at
(time):在此之后运行工作(可能在将来)
:queue
(string):命名为排列此作业的队列,替代优先级(请参见下文)
这些参数可以是PROC对象,从而允许对该值进行呼叫时间评估。
例如:
班级longtasks def send_mailer#其他一些代码 结尾 hander_asynchrony:send_mailer,:Priority => 20 def in_the_future#其他代码 结尾 #5.minutes.from_now将在in_the_future时评估 handle_asynchronicaly:in_the_future,:run_at => proc.new {5.minutes.from_now} def self.when_to_run2.hours.from_now 结尾 class << selfdef call_a_class_method#其他其他codeendhandle_asynchronely:call_a_class_method,:run_at => proc.new {when_to_run} 结尾 attr_reader:how_important def call_an_instance_method#其他代码 结尾 handle_asynchrony:call_an_instance_method,:Priority => proc.new {| i | i.how_important}结束
如果您想在没有延迟的工作中调用handle_asynchronously
方法,例如,在调试控制台上的某些内容时,只需将_without_delay
添加到方法名称中即可。例如,如果您的原始方法是foo
,请致电foo_without_delay
。
延迟的工作使用特殊语法用于铁路邮件。使用.delay
时,请勿调用.deliver
方法。
#毫不delayed_jobnotifier.signup(@user).deliver#witheed_jobnotifier.delay.signup(@user)#delaysed_job在特定的timenotifier.delay(run_at:run_at:run_at:5.minutes.from_now)使用parameters#parameters#时,必须在.delay methodnotifier.with(foo:1,bar:2).delay.signup(@user)之前调用.delay方法。
您可能还希望考虑使用Action Mailer使用Active Job,该邮件提供了方便的.deliver_later
语法,该语法将转发到延迟工作的工作。
DJ 3推出了名为队列的Resque Style,同时仍保留DJ风格的优先级。目的是提供一个系统,以分组任务由单独的工人池进行,可以单独缩放和控制。
可以通过设置queue
选项将作业分配给队列:
object.delay(:queue =>'tracking')。methodDelayed :: job.enqueue job,:queue =>'tracking'handle_asynchronicaly:tweet_later,:queue =>'tweets'
您可以为命名队列配置默认优先级:
延迟:: worker.queue_attributes = { high_priority:{优先级:-10}, low_priority:{优先级:10}}
配置的队列优先级可以通过将优先级传递给延迟方法来超越
object.delay(:queue =>'high_priority',优先级:0).method
您可以启动进程,只使用以下定义的queue
和queues
选项来工作某些队列。工艺始于未指定队列的情况下,将从任何队列中运行作业。为了有效地运行未指定队列的作业的过程,请设置一个默认的队列名称,并使用Delayed::Worker.default_queue_name
设置默认的队列名称,并使流程运行该队列。
script/delayed_job
可用于管理将开始工作的背景过程。
为此,请将gem "daemons"
添加到您的Gemfile
中,并确保您运行的rails generate delayed_job
。
然后,您可以执行以下操作:
RAILS_ENV=production script/delayed_job start RAILS_ENV=production script/delayed_job stop # Runs two workers in separate processes. RAILS_ENV=production script/delayed_job -n 2 start RAILS_ENV=production script/delayed_job stop # Set the --queue or --queues option to work from a particular queue. RAILS_ENV=production script/delayed_job --queue=tracking start RAILS_ENV=production script/delayed_job --queues=mailers,tasks start # Use the --pool option to specify a worker pool. You can use this option multiple times to start different numbers of workers for different queues. # The following command will start 1 worker for the tracking queue, # 2 workers for the mailers and tasks queues, and 2 workers for any jobs: RAILS_ENV=production script/delayed_job --pool=tracking --pool=mailers,tasks:2 --pool=*:2 start # Runs all available jobs and then exits RAILS_ENV=production script/delayed_job start --exit-on-complete # or to run in the foreground RAILS_ENV=production script/delayed_job run --exit-on-complete
铁轨4:用bin/delayed_job替换脚本/delayed_job
只要工人可以访问数据库并且时钟是同步的,就可以在任何计算机上运行。请记住,每个工人至少将每5秒至少检查数据库。
您还可以调用rake jobs:work
。您可以使用CTRL-C
取消Rake任务。
如果您只想运行所有可用的作业和退出,则可以使用rake jobs:workoff
通过设置QUEUE
或QUEUES
环境变量来解决队列。
QUEUE=tracking rake jobs:work QUEUES=mailers,tasks rake jobs:work
以下语法将重新启动延迟作业:
RAILS_ENV=production script/delayed_job restart
重新启动多个delayed_job工人:
RAILS_ENV=production script/delayed_job -n2 restart
铁轨4:用bin/delayed_job替换脚本/delayed_job
作业是简单的红宝石对象,具有称为permion的方法。任何响应性能的对象都可以塞入工作表中。作业对象已序列化为YAML,以便以后可以由工作跑者复活。
newsletterjob = struct.new(:text,:emails)做 def performails.each {| e | newslettermailer.deliver_text_to_email(文本,e)} endendDelayed :: job.enqueue newsletterjob.new('lorem ipsum ...',cunituts.pluck(:email))
为了设置覆盖延迟:: worker.max_attempt的每个人的最大尝试
newsletterjob = struct.new(:text,:emails)做 def performails.each {| e | newslettermailer.deliver_text_to_email(文本,e)} 结尾 def max_attempts3 终点
要设置覆盖延迟:: worker.max_run_time的每个人的最大运行时间,您可以在作业上定义max_run_time方法
注意:这只能用于设置MAX_RUN_TIME,该tay :: worker.max_run_time。否则,工作的锁将到期,另一名工人将开始从事进步工作。
newsletterjob = struct.new(:text,:emails)做 def performails.each {| e | newslettermailer.deliver_text_to_email(文本,e)} 结尾 def max_run_time120#秒 终点
为了设置一个每工作默认值来破坏失败的作业,该作业覆盖了延迟:: worker.destroy_failed_jobs,您可以定义Destroy_failed_jobs?工作方法
newsletterjob = struct.new(:text,:emails)做 def performails.each {| e | newslettermailer.deliver_text_to_email(文本,e)} 结尾 def destroy_failed_jobs?false 终点
要为覆盖延迟的自定义作业设置默认队列名称:: worker.default_queue_name,您可以在作业上定义queue_name方法
newsletterjob = struct.new(:text,:emails)做 def performails.each {| e | newslettermailer.deliver_text_to_email(文本,e)} 结尾 def queue_name'newsletter_queue' 终点
错误时,该作业在5秒内再次安排在 + n ** 4之内,其中n是尝试的数量。您可以定义自己的reschedule_at
方法来覆盖此默认行为。
newsletterjob = struct.new(:text,:emails)做 def performails.each {| e | newslettermailer.deliver_text_to_email(文本,e)} 结尾 def reschedule_at(current_time,trims)current_time + 5.秒 终点
您可以在此过程中在不同阶段被调用的工作中定义钩子:
注意:如果您使用的是ActiveJob,则这些挂钩无法提供工作。您将需要使用ActiveJob的回调。您可以在此处找到详细信息
类ParanoidNewsletterjob <新闻通讯 DEF ENQUEUE(JOB)RECORD_STAT“ newsletter_job/enqueue' 结尾 def performails.each {| e | newslettermailer.deliver_text_to_email(文本,e)} 结尾 def(job)record_stat'newsletter_job/start' 结尾 def之后(job)record_stat'newsletter_job/efter'之后' 结尾 DEF Success(Job)record_stat“ newsletter_job/Success” 结尾 def错误(作业,例外)airbrake.notify(异常) 结尾 def失败(作业)page_sysadmin_in_the_middle_of_the_night 终点
该库围绕一个延迟的_jobs表旋转,该表如下:
create_table:delayed_jobs,:force => true do |表| table.integer:优先级,:default => 0#允许一些作业跳到队列的前部 table.integer:尝试,:default => 0#提供重试,但最终仍然失败。 Table.Text:处理程序#YAML编码的对象的字符串将有效 Table.Text:Last_error#最后失败的原因(请参阅下面的注释) table.datetime:run_at#何时运行。可能是时间。 table.datetime:locked_at#设置客户端在此对象上工作时 table.datetime:Failed_at#设置所有重试时(实际上,默认情况下,记录被删除)) table.string:locked_by#谁在此对象上工作(如果锁定) table.string:队列#队列的名称此作业在 Table.Timestampsend
错误时,该作业将在5秒内再次安排,其中n是尝试数或使用作业定义的reschedule_at
方法。
默认Worker.max_attempts
为25。此后,该作业要么被删除(默认),要么以“ failed_at”设置在数据库中。随着25次尝试的违约,最后一次重试将在20天后,最后一个间隔将近100小时。
默认Worker.max_run_time
是4.小时。如果您的工作需要更长的时间,另一台计算机可以接收。确保您的工作不会超过这段时间,取决于您。您应该将其设置为最长的时间,您认为这项工作可能会花费。
默认情况下,它将删除失败的作业(并且总是删除成功的作业)。如果要保持失败的作业,请设置Delayed::Worker.destroy_failed_jobs = false
。失败的作业将用非null Failed_at标记。
默认情况下,所有作业均以priority = 0
进行安排,这是当务优先级。您可以通过Delayed::Worker.default_priority
设置为其他东西来更改此操作。较低的数字具有较高的优先级。
默认行为是在找到可用作业时从队列中读取5个作业。您可以通过设置Delayed::Worker.read_ahead
来配置此功能。
默认情况下,所有作业将在没有命名队列的情况下排队。可以通过使用Delayed::Worker.default_queue_name
来指定名为Queue的默认值。
如果找不到工作,工人会在睡眠延迟选项指定的时间内睡觉。设置Delayed::Worker.sleep_delay = 60
持续60秒的睡眠时间。
可以禁用延迟作业以进行测试。设置Delayed::Worker.delay_jobs = false
实时执行所有作业。
或Delayed::Worker.delay_jobs
可以是决定是否以每个工作为基础执行工作的Proc:
延迟:: worker.delay_jobs = - >(job){ job.queue!='inline'}
您可能需要提出sigterm信号的例外, Delayed::Worker.raise_signal_exceptions = :term
将导致工人提出一个SignalException
导致跑步工作中止并解锁,这使得其他工人可用于其他工人。此选项的默认值为false。
这是导轨中改变作业参数的示例:
#config/initializers/delayed_job_config.rbdelayed :: worker.destroy_failed_jobs = falsedelayed :: worker.sleep_delay = 60delay = 60delay :: worker.max_atterments = 3deLement = 3delayed :: worker.max_run_time_time = 5.minet worres.mine torresney :: er.minitedery.need :: el.eled :: elyed :: AME ='default'delayed :: worker.delay_jobs =!rails.env.test?delayed :: worker.raise.raise_signal_exceptions =:termDelayed :: worker.logger = logger.new(file.join(rails.rails.rails.roots.Roots.Roots.Root,'log'',',',',',',',',',',',',',',',',',',',',',',',',',',',',',',',',',',',',',',, delayed_job.log'))
您可以调用rake jobs:clear
以删除队列中的所有作业。
获得帮助的好地方是:
Google组,您可以在其中加入我们的邮件列表。
stackoverflow