Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Rails 7.1.0 Active Job CHANGELOG(翻訳)

概要

MITライセンスに基づいて翻訳・公開いたします。

参考: Active Job の基礎 - Railsガイド

rc2以後の更新はありません。

🔗 Active Job CHANGELOG(7.1.0.rc2)

🔗 Make sure scheduled_at is a Time object when asserting enqueued jobs · rails/rails@69d65b8

エンキュージョブのアサーションでscheduled_atTimeオブジェクトになるよう修正。

Rafael Mendonça França
同CHANGELOGより

🔗 Active Job CHANGELOG(7.1.0.rc1)

🔗 Set, serialize, and deserialize Active Job scheduled_at as Time; deserialize enqueued_at as Time; deprecate setting scheduled_at= with numeric/epoch by bensheldon · Pull Request #48066 · rails/rails

scheduled_at属性をepoch秒ではなくTimeオブジェクトとして設定し、エンキュー時にこの値をシリアライズ/デシリアライズするようになった。

scheduled_at=にnumeric値やepoch値を代入することは非推奨化された。今後はTimeオブジェクトを使うこと。

enqueued_atのデシリアライズは、ISO8601文字列ではなくTimeとして行われるようになる。

Ben Sheldon
同CHANGELOGより

参考: Rails API ActiveJob::Core
参考: ISO 8601 - Wikipedia
参考: UNIX時間(エポック秒 / POSIX時間)とは - 意味をわかりやすく - IT用語辞典 e-Words

🔗 Clarify that the default retry strategy uses polynomial backoff instead of exponential backoff by victormours · Pull Request #49292 · rails/rails

ジョブのリトライで、:waitオプションで推奨されるバックオフ戦略を明確にした。

従来のwait: :exponentially_longerは、実際にはリトライ間の待ち時間が多項式時間で増加するので、従来と同じ振る舞いを維持するにはwait: :polynomially_longerを指定することが推奨される。

Victor Mours
同CHANGELOGより

参考: 週刊Railsウォッチ20131004: Active Jobのリトライオプションにwait: :polynomially_longerを追加し、wait: :exponentially_longerを非推奨化

🔗 Active Job CHANGELOG(v7.1.0.beta1)

🔗 Fix Active Job log message to correctly report a job failed to enqueue when the adapter raises an ActiveJob::EnqueueError by bensheldon · Pull Request #47865 · rails/rails

ActiveJob::EnqueueErrorが発生した場合にActive Jobログメッセージでジョブのエンキューに失敗したことを正しく報告するよう修正。

Ben Sheldon
同CHANGELOGより

この修正は、Rails 7.0.8でリリース済みです。

🔗 Add after_discard method to ActiveJob by cardy31 · Pull Request #48010 · rails/rails

after_discardメソッドを追加。

ジョブの作成者はこのメソッドを使うことで、ジョブが破棄される直前に実行されるブロックを以下のように定義できるようになる。

class AfterDiscardJob < ActiveJob::Base
  after_discard do |job, exception|
    Rails.logger.info("#{job.class} raised an exception: #{exception}")
  end

  def perform
    raise StandardError
  end
end

上記のジョブは、ジョブが破棄された後に after_discard に渡されたブロックを実行する。この例外は、ブロックが実行された後でも発生する。

Rob Cardy
同CHANGELOGより

参考: 週刊Railsウォッチ20230906: Active Jobにafter_discardフックが追加

🔗 Fix invalid durations with ActiveJob deserialization by jdelStrother · Pull Request #44262 · rails/rails

ActiveSupport::Durationのデシリアライズを修正。

従来は、デシリアライズされたDurationDuration#partsから配列を返すことがあった。
今後は、通常のDurationと同様にハッシュを返すようになる。

これにより、デシリアライズされたDurationに対する加算や減算(例:duration + 1.year)のエラーも修正される。

Jonathan del Strother
同CHANGELOGより

参考: Rails API ActiveSupport::Duration

🔗 Make perform_enqueued_jobs compatible with all Active Job adapters by ghiculescu · Pull Request #48599 · rails/rails

perform_enqueued_jobsがActive Jobアダプタ互換になった。

これは、:testアダプターが使われていない場合であっても、これに依存するメソッド(Action Mailerのassert_emailsなど)がtest環境で正しく動作することを意味する。

Alex Ghiculescu
同CHANGELOGより

参考: Rails API perform_enqueued_jobs -- ActiveJob::TestHelper

🔗 Allow queue adapters to provide a custom name by Mangara · Pull Request #48003 · rails/rails

queue_adapter_nameを実装することでキューアダプタにカスタム名を与えられるようになった。

Sander Verdonschot
同CHANGELOGより

# 同PRより
  class StubFourAdapter
    def enqueue(*); end
    def enqueue_at(*); end
    def queue_adapter_name
      "fancy_name"
    end
  end

  test "should use the name provided by the adapter" do
    child_job = Class.new(ActiveJob::Base)
    child_job.queue_adapter = StubFourAdapter.new
    assert_equal "fancy_name", child_job.queue_adapter_name
  end

参考: Rails API queue_adapter_name --ActiveJob::QueueAdapter::ClassMethods

🔗 Add support for logging background job enqueue callers by fatkodima · Pull Request #47839 · rails/rails

バックグラウンドのジョブエンキューの呼び出し元をログ出力できるようになった。

デバッグを支援するために、バックグラウンドジョブのエンキュー呼び出し元をログ出力するverbose_enqueue_logs設定オプションを追加した。。

ログ出力の例:

Enqueued AvatarThumbnailsJob (Job ID: ab528951-41fb-4c48-9129-3171791c27d6) to Sidekiq(default) with arguments: 1092412064
↳ app/models/user.rb:421:in `generate_avatar_thumbnails'

新規アプリケーションやアップグレードされたアプリケーションでは、development環境でのみ有効になる。RubyのKernel#callerに依存しており、かなり遅いため、本番環境での利用は推奨されていない。

fatkodima
同CHANGELOGより

Rails 7.1: バックグラウンドジョブのenqueue呼び出し元をログ出力可能になった(翻訳)

🔗 implement provider_job_id for Backburner jobs by cmatheson · Pull Request #47732 · rails/rails

Backburnerのジョブにprovider_job_idを設定するようになった。

Cameron Matheson
同CHANGELOGより

参考: 週刊Railsウォッチ20230425: Backburnerジョブ用のprovider_job_idが実装された

nesquena/backburner - GitHub

🔗 Add perform_all_later to enqueue multiple jobs at once by Mangara · Pull Request #46603 · rails/rails

複数ジョブを一括エンキューするperform_all_laterを追加。

以下のように複数のジョブまたはジョブの配列を渡すことで、コールバックを実行せずにジョブを一括エンキューする機能が追加された。

ActiveJob.perform_all_later(MyJob.new("hello", 42), MyJob.new("world", 0))

user_jobs = User.pluck(:id).map { |id| UserJob.new(user_id: id) }
ActiveJob.perform_all_later(user_jobs)

これにより、キューデータストアとのやりとりを大幅に削減可能。
新しいenqueue_allメソッドを実装していないキューアダプターでは、ジョブを個別にエンキューする形にフォールバックする。なお、Sidekiqアダプターはpush_bulkenqueue_allを実装している。

このメソッドは既存のenqueue.active_jobイベントを使わずに、新しいイベントenqueue_all.active_jobイベントを追加する。

Sander Verdonschot
同CHANGELOGより

Rails 7.1: 複数ジョブを一度にエンキューするperform_all_laterが追加(翻訳)

🔗 Fix double logging in ActiveRecord::QueryLogs by ghiculescu · Pull Request #46279 · rails/rails

ActiveRecord::QueryLog利用中に jobのログ出力が重複しないように修正。

従来は、:jobを含む配列をconfig.active_record.query_log_tagsに設定すると、ジョブ名が2回出力されることがあった。このバグは修正された。

Alex Ghiculescu
同CHANGELOGより

この修正は、Rails 7.0.5でリリース済みです

🔗 Use a higher-level Sidekiq API for ActiveJob by jdelStrother · Pull Request #46080 · rails/rails

SidekiqのTransactionAwareClientのサポートを追加。

Jonathan del Strother
同CHANGELOGより

🔗 Remove QueAdapter from Active Job by yahonda · Pull Request #46005 · rails/rails

Active JobのQueAdapterを削除。

Active Job QueAdapterを、Railsとque gemの両面でRuby 3のキーワード引数とオプションをトップレベルのキーワードとしてサポートするようメンテナンスしてきたが、この方法でのメンテナンスはかなり困難。

今後、que gem自体にActive Job Queアダプターが含まれるかもしれない。

Yasuo Honda
同CHANGELOGより

que-rb/que - GitHub

🔗 Fix BigDecimal(de)serialization for JSON adapters by sambostock · Pull Request #45618 · rails/rails

JSONを使っているアダプタのBigDecimalシリアライズ/デシリアライズを修正。

従来のBigDecimalではシリアライザは不要とされていた。しかし、ジョブの引数をJSONとして保存するアダプターで使うと、単なるStringとしてシリアライズされ、デシリアライズでも BigDecimalではなくStringが生成されてしまっていた。

シリアライザを導入することで、変換と逆変換が安全に行われるようになる。

BigDecimalジョブ引数を使うアプリケーションがデプロイ中に競合状態になる(BigDecimalSerializerでシリアライズした引数を、実行中のレプリカRailsでデシリアライズできない場合)のを防ぐため、ActiveJob.use_big_decimal_serializer設定はデフォルトでは無効になっている。この設定は次回のデプロイでtrueに設定できる。

Sam Bostock
同CHANGELOGより

参考: config.active_job.use_big_decimal_serializer -- Rails アプリケーションを設定する - Railsガイド

🔗 Preserve job.enqueued_at timestamp precision by jeremy · Pull Request #45580 · rails/rails

シリアライズされたジョブにおけるフル精度のenqueued_atタイムスタンプの精度を維持することで、ジョブ実行前のキュー待機時間をより正確に報告するようになった。

IS08601形式との互換性を維持している。

Jeremy Daer
同CHANGELOGより

🔗 Add --parent option to job generator to specify parent class of job. by gmcgibbon · Pull Request #45528 · rails/rails

ジェネレータで生成するジョブの親クラスを指定する--parentオプションを追加。

例: bin/rails g job process_payment --parent=payment_jobで以下のジョブクラスが生成される。

class ProcessPaymentJob < PaymentJob
  # ...
end

Gannon McGibbon
同CHANGELOGより

🔗 Add more detailed description to job generator by gmcgibbon · Pull Request #45327 · rails/rails

ジョブジェネレータの詳しい利用法をヘルプに追加。

Gannon McGibbon
同CHANGELOGより

🔗 Add db_runtime to Active Job instrumentation by jonathanhefner · Pull Request #40058 · rails/rails

perform.active_jobの通知ペイロードに:db_runtimeを追加。
これは、ジョブの実行中にデータベースクエリで要した合計時間(単位はms)。

この値で、ジョブ実行時間の消費状況をより良く理解できるようになる。

Jonathan Hefner
同CHANGELOGより

参考: perform.active_job -- Active Support の Instrumentation 機能 - Railsガイド

🔗 Update ActiveJob QueAdapter for future compatibility by sidonath · Pull Request #44734 · rails/rails

ActiveJob::QueueAdapters::QueAdapterを更新して非推奨警告を削除。

Ruby 3との互換性に必要なque 2.0 の変更に備えて、que 1.2で導入された非推奨警告を削除した。

Damir Zekic and Adis Hasovic
同CHANGELOGより

que-rb/que - GitHub

🔗 Add missing bigdecimal require in ActiveJob::Arguments by byroot · Pull Request #44411 · rails/rails

ActiveJob::Argumentsrequire "bigdecimal"を追加。

Active Jobを別途読み込んだときにuninitialized constant ActiveJob::Arguments::BigDecimal (NameError)が発生する可能性があった。

Jean Boussier
同CHANGELOGより

🔗 Allow testing discard_on/retry_on ActiveJob::DeserializationError by intrip · Pull Request #43066 · rails/rails

discard_on/retry_on ActiveJob::DeserializationErrorがテスト可能になった。

従来は、perform_enqueued_jobs内でperform_nowを呼び出す前にdeserialize_arguments_if_neededが呼び出されていた。
つまり、レコードが存在せず、GlobalIDを用いてシリアライズしていた場合、perform_now呼び出しの前にActiveJob::DeserializationErrorが発生していた。

この振る舞いによって、ジョブのdiscard_on/retry_onのロジックのテストが困難になっていた。

このdeserialize_arguments_if_needed呼び出しが、perform_now呼び出し時まで延期されるように修正された。

例:

class UpdateUserJob < ActiveJob::Base
  discard_on ActiveJob::DeserializationError

  def perform(user)
  # ...
  end
end

# テストコード内
User.destroy_all
assert_nothing_raised do
  perform_enqueued_jobs only: UpdateUserJob
end

Jacopo Beschi
同CHANGELOGより

参考: 週刊Railsウォッチ20220117: Active Jobのシリアライズテストの失敗時にdiscard_onretry_onを利用できるよう修正


以前の変更については7-0-stableのCHANGELOGを参照。

関連記事

Rails 7.1に入る主要な機能まとめ(1)update_attribute!、CTEサポートほか(翻訳)

Rails 7.1に入る主要な機能まとめ(2)error_highlight対応、routes --grepほか(翻訳)

Rails 7.1に入る主要な機能まとめ(3)Docker関連ファイル導入ほか(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。