⚠️

Sidekiq 6.5 から 7.2.2 アップグレード時のトラブルと対応策

に公開

sidekiqバージョンアップ

Gemfile
- gem 'sidekiq', '~> 6.5'
+ gem 'sidekiq', '~> 7.2.2'

プロジェクトでSidekiq を 6.5 から 7.2.2にアップグレードした際に発生した問題と、その対応策をまとめました。

1. Strict Argument(厳密な引数チェック機能)によるエラー

Sidekiq 7 から Strict Argument(厳密な引数チェック機能)がデフォルトで例外を発生させるようになりました。

  • Sidekiq 6.4.0で導入された Strict Argument は、ジョブの引数がネイティブな JSON 型になっていることを検証し、不正な場合は警告を出力する仕組みでした。
  • Sidekiq 7では、これがさらに厳しくなり、不正な引数があるとArgumentErrorを発生 させるようになりました。

ネイティブな JSON 型とは?

以下の型のみが許容される

  • 文字列(String)
  • 数値(Integer / Float)
  • 真偽値(Boolean)
  • nil
  • 配列(Array)
  • これらの値を持つ純粋なハッシュ(Hash)
    • Hash のキーは 文字列 でなければならない

発生した問題

以下はエラーの例です。

ArgumentError: Job arguments to OndemandAppSyncWorker must be native JSON types, 
but {"sku_codes"=>["test-000001", "test-000002"]} is a ActiveSupport::HashWithIndifferentAccess

原因: ActiveSupport::HashWithIndifferentAccess はネイティブ JSON 型ではないため、エラーが発生。

ArgumentError: Job arguments to File::DownloadWorker must be native JSON types, 
but #<ActionController::Parameters {"target"=>"all", "id"=>"", "corporate_name"=>"", 
"corporate_number"=>"", "status"=>"valid", "sort"=>"id", "desc"=>1} permitted: false> 
is a ActionController::Parameters

原因: ActionController::Parameters はネイティブ JSON 型ではないため、エラーが発生。

ArgumentError: Job arguments to SlackClientCheckNotifier must be native JSON types, 
but :create is a Symbol.

原因: Symbol は JSON に変換できないため、エラーが発生。

native JSON types, but Wed, 12 Mar 2025 17:40:35.507528000 JST +09:00 is a ActiveSupport::TimeWithZone.

原因: ActiveSupport::TimeWithZone も JSON 型ではないためエラーが発生。

対応方法

perform_async に渡す引数を ネイティブな JSON 型に変換。
以下は変換の例です。

  • HashWithIndifferentAccess を Hash に変換
ruby
- worker.perform_async(search_params.to_h)
+ worker.perform_async(search_params.to_hash) 
  • ActionController::Parameters を Hash に変換
ruby
- worker.perform_async(params)
+ worker.perform_async(params.to_hash)
  • SymbolString に変換
ruby
- worker.perform_async(:create)
+ worker.perform_async(:create.to_s)
  • TimeWithZone を ISO 8601 形式に変換
ruby
- worker.perform_async(time)
+ worker.perform_async(time.iso8601)

参考:Implement strict argument checking

2. Sidekiq のタスクが無限再起動してしまう

発生した問題

CI 環境(AWS Deploy の Staging)で Sidekiq のタスクが無限に再起動 する現象が発生しました。

INFO[0018] (service ********-staging-sidekiq) has started 1 tasks: (task 85f2eb2792934f0aaeb753fa7a60287f).  timestamp="2025-03-18 07:08:14 +0000 UTC"
INFO[0072] Service status                                desiredCount=1 runningCount=2 serviceName=********-staging-sidekiq
INFO[0089] Service status                                desiredCount=1 runningCount=1 serviceName=********-staging-sidekiq
INFO[0121] (service ********-staging-sidekiq) has started 1 tasks: (task beb782de095b4fc78b9816071fb21bdc).  timestamp="2025-03-18 07:09:56 +0000 UTC"
INFO[0180] Service status                                desiredCount=1 runningCount=2 serviceName=********-staging-sidekiq
INFO[0202] Service status                                desiredCount=1 runningCount=1 serviceName=********-staging-sidekiq
・
・
・
INFO[4784] (service ********-staging-sidekiq) has started 1 tasks: (task 74cd52904edc47e586b8813ebe4a631a).  timestamp="2025-03-18 08:27:37 +0000 UTC"
INFO[4860] Service status                                desiredCount=1 runningCount=2 serviceName=********-staging-sidekiq
INFO[4876] Service status      

CloudWatch のログを確認すると、以下のエラーが出ていました。

2025-03-18T08:17:08.267Z pid=1 tid=4zh INFO: Sidekiq 7.2.4 connecting to Redis with options 
{:size=>10, :pool_name=>"internal", :url=>"redis://herokura-staging.vg1jxe.0001.apne1.cache.amazonaws.com:6379"}

redis-client requires Redis 6+ with HELLO command available (redis://herokura-staging.vg1jxe.0001.apne1.
cache.amazonaws.com:6379)

原因

Sidekiq 7.2.4 は Redis 6 以上の HELLO コマンドを必要とするが、接続先の Redis が 4.0.10 だったためエラーが発生。

対応方法

AWS ElastiCache の Redis エンジンを 6 系に メジャーアップグレード 。

参考:Amazon ElastiCache for Redisのメジャーアップグレード方法をまとめてみた

まとめ

  1. Strict Argument(厳密な引数チェック機能)が強化
  • Sidekiq 7 では、ジョブの引数がネイティブ JSON 型でない場合、ArgumentError が発生するようになった。
  • ActiveSupport::HashWithIndifferentAccess、ActionController::Parameters、Symbol、ActiveSupport::TimeWithZone などが原因でエラー発生。
  • 対応策: perform_async に渡す前に、適切な型に変換。
  1. Sidekiq 7.2.4 が Redis 6+ の HELLO コマンドを要求
  • 既存の ElastiCache Redis のバージョンが 4.0.10 であり、Sidekiq 7.2.4 に必要な Redis 6 の HELLO コマンドが使用できずエラー発生。
  • 対応策: ElastiCache Redis のバージョンを 6.x にメジャーアップグレード。

Discussion