やわらかテック

興味のあること。業務を通して得られた発見。個人的に試してみたことをアウトプットしています🍵

sidekiq.ymlファイルの文字列に環境変数を埋め込む

sidekiq.ymlではERBがサポートされており、環境変数を指定することが可能です。
よく環境変数が使われるのは、並行度(concurrency)の値やタイムアウトの秒数などでしょうか。

:concurrency: <%= ENV.fetch('SIDEKIQ_CONCURRENCY', 10) %>

こんな感じでsidekiq.yml内で、環境変数を扱うのは非常に簡単です。
ですが、文字列(値)に環境変数を埋め込むにはどうすれば良いのでしょうか。
今回、自分がやりたかったのはcronの設定値の実行間隔(分)の部分だけを環境変数から指定するというものです。

# 30...の箇所を環境変数から指定したい
cron: '0 30 * * * * Asia/Tokyo'

自分が調べた限りでは、該当する記事が見つからなかったので記事にまとめてみました。

環境変数の埋め込み方

これで問題なく動作しました。
ENV.fetch内部で文字列を指定するため、ダブルクォーテーションを使う必要があります。

:schedule:
    sample_worker:
      cron: "0 <%= ENV.fetch('RUNTIME_MINUTES', '0/1') %> * * * * Asia/Tokyo"
      class: SampleWorker

sidekiq.ymlに上記を指定した状態で立ち上げてみると、無事に値の解釈と、スケジューリングの読み込みがされていることが分かります。

INFO: Booted Rails xxxx application in development environment
INFO: Running in ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux]
INFO: See LICENSE and the LGPL-3.0 for licensing details.
INFO: Upgrade to Sidekiq Pro for more features and support: https://sidekiq.org
INFO: Loading Schedule
INFO: Scheduling sample_worker {"cron"=>"0 0/1 * * * * Asia/Tokyo", "class"=>"SampleWorker", "queue"=>"default"}

あまりERBには詳しくないので、どのような過程で値の解釈がされているのかは分かりかねますが、Rubyで文字列内に変数を埋め込めるのと同じ考え方で問題なさそうです。

person = "takeshi"
puts "hello #{person} !!" # hello takeshi !!

他のパターン

ERBではRubyの構文が自由に記述可能なので、さまざまな記述が可能でした。
使うケースはほとんどないと思いますが、紹介だけしておきます。

ランダム値を使う

cron: "0 <%= '0/'.concat(rand(10).to_s) %> * * * * Asia/Tokyo"
INFO: Scheduling sample_worker {"cron"=>"0 0/4 * * * * Asia/Tokyo", "class"=>"SampleWorker", "queue"=>"default"}

ERBの中に全部書く

cron: <%= "0 ".concat(ENV.fetch("RUNTIME_MINUTES", "0/1")).concat(" * * * * Asia/Tokyo") %>
INFO: Scheduling sample_worker {"cron"=>"0 0/1 * * * * Asia/Tokyo", "class"=>"SampleWorker", "queue"=>"default"}

少しでも「ええな〜」と思ったらはてなスター・はてなブックマーク・シェアを頂けると励みになります。