自作の gem の名前を考えるのは難しい
自作の gem の名前を変えたい。
my_api_client
という自作の gem がありまして、このブログでは何度も紹介している んですが、ニッチすぎるのか宣伝が下手すぎるのか、一向に使ってみた、という噂を聞きません (´・ω・`)
まあ弊社のプロダクトの中ではガッツリ使ってるんで別にそれは良いんですが、もう少しまともな名前にならんのかね、というコメントを頂きます。 いい機会だしちゃんと良い名前付けようと思って考えました。どうせなら自分が好きなゲームからいい名前付けたいな、と思って『Luida(ルイーダ)』という名前が浮かびました。ドラクエ III のあれです。
my_api_client
は API Client を簡単に作ったりテストしたりするための gem なので、冒険者を登録して一緒に旅するルイーダの店のイメージがピッタリだなーと思ったんですよね。とはいえ gem の名前を変えるのって面倒だしそのうちやろう、って思ってたら半年くらい経っちゃいましたけどね。上のルイーダの店の画像ってわざわざ iPhone 版のドラクエIII 買ってスクショ撮ったんですが、その日付が 2020/10/04 でした 😇
多分そのうちやります(フラグ)
my_api_client v0.20.0 をリリースしました 🚀
gem の名前は変わらないけどアップデートはされていく。
元々 my_api_client
には #pageable_get
(alias: #pget
) というメソッドがあり、REST API のレスポンス JSON に含まれる URL を順に辿ってリクエストする Enumerator
を取得することが出来ます。機能自体は実相してテストもしてあるものの、実際のプロダクトで使う機会がなく長いこと日の目を見なかったんですが、この度ついに弊プロダクトで利用する機会が訪れたのでチームのエンジニアに使ってもらってるんですが、 RSpec を書く際のスタブ化が特にサポートされていなくてテストしづらい問題がありました。
今回のアップデートでは、この #pageable_get
に対応するスタブ化をサポートしています。 詳しい解説は README.jp.md にも書いた んですが、せっかくなのでブログにも転記しておきます。まあ文章で説明されても実際に使ってみないとピンと来ないのはわかってますけどね。。。
#pageable_get
(#pget
) を使った実装用に pageable
というオプションが利用できます。
pageable
に設定する値は Enumerable
である必要があります。
stub_api_client_all( MyPaginationApiClient, pagination: { pageable: [ { page: 1 }, { page: 2 }, { page: 3 }, ], } ) MyPaginationApiClient.new.pagination.each do |response| response.page #=> 1, 2, 3 end
なお、 Enumerable
の各値にはここまで紹介した response
, raise
, Proc
など全てのオプションが利用可能です。
stub_api_client_all( MyPaginationApiClient, pagination: { pageable: [ { response: { page: 1 } }, { page: 2 }, ->(params) { { page: 3, user_id: params[:user_id] } }, { raise: MyApiClient::ClientError::IamTeapot }, ], } )
また、 Enumerator
を使えば無限に続くページネーションを定義することもできます。
stub_api_client_all( MyPaginationApiClient, pagination: { pageable: Enumerator.new do |y| loop.with_index(1) do |_, i| y << { page: i } end end, } )
ActiveJob の retry_on に jitter というオプションがあるの知ってますか?
僕は知らなかったです (・∀・)
Rails で ActiveJob の retry_on が同時に発火されるの何とかしたいなーと思って調べてたら、Rails 6 からは jitter というオプションが指定できるようになってて、デフォルトでリトライ間隔を 15% ランダマイズしてくれるとの事。Rate Limit の回避とかで便利。 https://t.co/kpIx6YVFEq
— サトウリョウスケ (@ryosuke_sato) February 27, 2021
jitter とは
Rails 6.1 から追加されたオプション で、 retry_on
の待ち時間に対して任意の割合でバラけさせてくれるようになります(デフォルト 15% )。
ActiveJob::Exceptions::ClassMethods - retry_on
:jitter
- A random delay of wait time used when calculating backoff. The default is 15% (0.15) which represents the upper bound of possible wait time (expressed as a percentage)
実装を確認してみた
このバラけさせ方が待ち時間に対して増えるのか減るのかが気になって実装を見てみました。増える方向でバラけるようです。
例えば wait: 60.seconds
で jitter: 0.5
の場合だと、最大 90
秒の待ち時間となります。
うっかり 100.0
とか指定すると最大 10000% 待ち時間が加算されちゃいそうです。
間違えて指定しないようにご注意下さい🙏
delay = seconds_or_duration_or_algorithm.to_i delay_jitter = determine_jitter_for_delay(delay, jitter) delay + delay_jitter
📝 jitter の計算処理は このあたり
どういう場面で使うの?
この機能が無かった従来だと、リトライ処理が一斉に起動してしまうという問題がありました。
例えば外部のサービスに API リクエストするような Job を作ったとします。API Rate Limit 超過の例外をハンドリングして、 retry_on
で N 分後にリトライするように実装します。
この時、 1000 件の Job が同時に実行され 900 件が Rate Limit 超過となった場合、N 分後に 900 件の Job が一斉にリトライされてしまい、再び 800 件がエラーとなってしまう。
これが何度も繰り返される、という現象が起こってました。
Rails 6.1 以前だと回避できないの?
従来の ActiveJob でも一応回避策はあって、 wait
に Proc
を与えてランダムな待ち時間を返すような処理を書くことで似たような動作は可能です。
retry_on SomeError, wait: -> { rand(60..90).seconds }
iPad Air (第4世代) 買っちゃった
RuboCop で違反してるコードを自動的に修正する PR 作ってくれたら嬉しいやろ。できるでそれ。
久々の更新は Rubocop Challenger の話です。
このブログでは触れたこと無かったですが、 そういう gem も作ってます。
自動的に .rubocop_todo.yml
から Cop supports --auto-correct.
になってる Cop を拾ってきて PR 作ってくれるやつです。
ちょうど hey 社の CTO の藤村さんが同じ事をやっていてちょっとバズってたんですが、自分の gem 使ってほしかったなーと地味に思ってたりします。自分が世の中に対してアピールが足りてなさすぎましたね 😇
何年か前に会社のブログで書いたりはしてたのでリンク貼っておく ✍
Rubocop Challenger v2.3.0 をリリースしました 🚀
とはいえ新機能は一つだけで、 auto-correct された Cop が SafeAutocorrect かどうかを教えてくれる、というものです。
こんな感じの PR が作成されます。(画像は動作確認で作ったものなので、実際の Style/Alias
は常に SafeAutocorrect: true
になります)
ぜひお試し下さい 👍
つぎやりたいこと
先日 GitHub が auto-merge 機能をリリースしましたね。自分は即全部のリポジトリで有効化しました ✅
次やりたい機能としては SafeAutocorrect: true
の場合とかは auto-merge を有効化した PR を作るようにしたいんですよね。
GitHub の GraphQL API でこの機能を有効化できるらしいです。
GraphQL APIs will be rolling out later this week. The pull request webhook event also now includes actions that indicate when auto-merge is enabled or disabled.
また時間ある時にでも調べます。