跳至内容 跳至搜索

Active Job – 让工作延迟执行

Active Job 是一个框架,用于声明作业并在各种排队后端上执行它们。这些作业可以是任何事情,从定期计划的清理、计费收费到邮件发送——任何可以分解成小的工作单元并并行运行的事情。

它还充当 Action Mailer 的 deliver_later 功能的后端,使轻松地将任何邮件变成待运行作业变得容易。这是现代 Web 应用程序中最常见的作业之一:在请求-响应周期之外发送电子邮件,这样用户就不必等待它。

重点是确保所有 Rails 应用程序都将拥有一个作业基础设施,即使是“立即运行程序”。然后,我们可以让框架功能和其他 gems 在其上构建,而无需担心 Delayed Job 和 Resque 之间的 API 差异。选择排队后端变得更多地是一个操作问题。并且您将能够在它们之间切换,而无需重写您的作业。

您可以在 Active Job 基础 指南中阅读更多关于 Active Job 的内容。

用法

要了解如何使用您喜欢的排队后端,请参阅其适配器文档,位于 ActiveJob::QueueAdapters

像这样声明一个作业

class MyJob < ActiveJob::Base
  queue_as :my_jobs

  def perform(record)
    record.do_work
  end
end

像这样将一个作业加入队列

MyJob.perform_later record  # Enqueue a job to be performed as soon as the queuing system is free.
MyJob.set(wait_until: Date.tomorrow.noon).perform_later(record)  # Enqueue a job to be performed tomorrow at noon.
MyJob.set(wait: 1.week).perform_later(record) # Enqueue a job to be performed 1 week from now.

就这样!

GlobalID 支持

Active Job 支持 GlobalID 序列化 用于参数。这使得将活动记录对象传递给您的作业而不是类/id 对成为可能,然后您必须手动反序列化它们。以前,作业看起来像这样

class TrashableCleanupJob
  def perform(trashable_class, trashable_id, depth)
    trashable = trashable_class.constantize.find(trashable_id)
    trashable.cleanup(depth)
  end
end

现在您只需

class TrashableCleanupJob
  def perform(trashable, depth)
    trashable.cleanup(depth)
  end
end

这适用于任何混合了 GlobalID::Identification 的类,默认情况下它已混合到活动记录类中。

支持的排队系统

Active Job 为多个排队后端(Sidekiq、Resque、Delayed Job 等)内置了适配器。要获取适配器的最新列表,请参阅 ActiveJob::QueueAdapters 的 API 文档。

请注意:我们不接受新适配器的拉取请求。我们鼓励库作者在其 gem 或作为独立 gem 中提供一个 ActiveJob 适配器。有关此讨论,请参阅以下 PR:2331121406#32285.

下载和安装

Active Job 的最新版本可以使用 RubyGems 安装

$ gem install activejob

源代码可以作为 GitHub 上 Rails 项目的一部分下载

许可证

Active Job 采用 MIT 许可证发布

支持

API 文档位于

Ruby on Rails 项目的错误报告可以在这里提交

功能请求应在 rails-core 邮件列表中讨论,地址如下:

命名空间
方法
G
P
V

类公开方法

gem_version()

返回当前加载的 Active Job 版本,以 Gem::Version 格式。

# File activejob/lib/active_job/gem_version.rb, line 5
def self.gem_version
  Gem::Version.new VERSION::STRING
end

perform_all_later(*jobs)

将多个作业一次性推送到队列中,而不运行加入队列回调。队列适配器可以通过在传入的作业实例上设置 successfully_enqueued 和/或 enqueue_error 来传达每个作业的加入队列状态。

# File activejob/lib/active_job/enqueuing.rb, line 14
def perform_all_later(*jobs)
  jobs.flatten!
  jobs.group_by(&:queue_adapter).each do |queue_adapter, adapter_jobs|
    instrument_enqueue_all(queue_adapter, adapter_jobs) do
      if queue_adapter.respond_to?(:enqueue_all)
        queue_adapter.enqueue_all(adapter_jobs)
      else
        adapter_jobs.each do |job|
          job.successfully_enqueued = false
          if job.scheduled_at
            queue_adapter.enqueue_at(job, job.scheduled_at.to_f)
          else
            queue_adapter.enqueue(job)
          end
          job.successfully_enqueued = true
        rescue EnqueueError => e
          job.enqueue_error = e
        end
        adapter_jobs.count(&:successfully_enqueued?)
      end
    end
  end
  nil
end

verbose_enqueue_logs

指定调用后台作业加入队列的方法是否应在其相关的加入队列日志行下方记录。默认值为 false。

# File activejob/lib/active_job.rb, line 57
singleton_class.attr_accessor :verbose_enqueue_logs

version()

返回当前加载的 Active Job 版本,以 Gem::Version 格式。

# File activejob/lib/active_job/version.rb, line 7
def self.version
  gem_version
end