略過至內容 略過至搜尋

Active Job — 稍後再執行工作

Active Job 是一個用來宣告工作並在各種排程後端作業的架構。這些工作可以是任何事務,從定期安排的清理工作、計費到郵件,任何事務都可以切成小型的工作單元,並平行執行。

它也作為 Action Mailer 的 deliver_later 功能後端,使任何郵件很容易轉換為稍後執行的工作。這是在現代網路應用程式中一種最常見的工作:在要求-回應週期外傳送電子郵件,這樣使用者就不必等待。

重點是確保所有 Rails 應用都在適當的位置具有工作基礎架構,即使它是「立即執行程式」的形式。接著我們可以在此基礎上建置架構功能和其他寶石,而不用擔心 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 序列化 的參數。這能將動態的 Active Record 物件傳遞給你的工作,而不用傳遞類別/ 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 Record 類別。

支援的排隊系統

Active Job 內建了多種排隊後端的介面(Sidekiq、Resque、Delayed Job 等)。如需取得介面的最新清單,請參閱 ActiveJob::QueueAdapters 的 API 文件。

請注意:我們不接受新增介面的 Pull Request。我們鼓勵函式庫作者提供 ActiveJob 介面作為寶石的一部分或獨立的寶石。討論這方面的資訊,請參閱以下 PR:2331121406#32285

下載和安裝

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

$ 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