逃げる8回で会心の一撃

Web エンジニアのサトウリョウスケが開発とか色々書くブログです

自作の gem の名前を考えるのは難しい

自作の gem の名前を変えたい。

my_api_client という自作の gem がありまして、このブログでは何度も紹介している んですが、ニッチすぎるのか宣伝が下手すぎるのか、一向に使ってみた、という噂を聞きません (´・ω・`)

github.com

まあ弊社のプロダクトの中ではガッツリ使ってるんで別にそれは良いんですが、もう少しまともな名前にならんのかね、というコメントを頂きます。 いい機会だしちゃんと良い名前付けようと思って考えました。どうせなら自分が好きなゲームからいい名前付けたいな、と思って『Luida(ルイーダ)』という名前が浮かびました。ドラクエ III のあれです。

f:id:ryz310:20201004001621j:plain:w300
ここはルイーダの店。旅人たちが仲間を求めてあつまる出会いと別れの酒場よ。

my_api_clientAPI Client を簡単に作ったりテストしたりするための gem なので、冒険者を登録して一緒に旅するルイーダの店のイメージがピッタリだなーと思ったんですよね。とはいえ gem の名前を変えるのって面倒だしそのうちやろう、って思ってたら半年くらい経っちゃいましたけどね。上のルイーダの店の画像ってわざわざ iPhone 版のドラクエIII 買ってスクショ撮ったんですが、その日付が 2020/10/04 でした 😇

多分そのうちやります(フラグ)

my_api_client v0.20.0 をリリースしました 🚀

gem の名前は変わらないけどアップデートはされていく。

github.com

元々 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 というオプションがあるの知ってますか?

僕は知らなかったです (・∀・)

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.secondsjitter: 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 でも一応回避策はあって、 waitProc を与えてランダムな待ち時間を返すような処理を書くことで似たような動作は可能です。

retry_on SomeError, wait: -> { rand(60..90).seconds }

iPad Air (第4世代) 買っちゃった

f:id:ryz310:20210302102542j:plain
iPad Air (第4世代)

近日中に iPad Pro の新型が出るとの噂があるが、軽い Air がほしかったので問題 🍆 (知らなかったけどね)

🔗 新型iPad Pro搭載A14X/A14Zチップの処理能力はM1チップに匹敵か - iPhone Mania

RuboCop で違反してるコードを自動的に修正する PR 作ってくれたら嬉しいやろ。できるでそれ。

久々の更新は Rubocop Challenger の話です。

このブログでは触れたこと無かったですが、 そういう gem も作ってます。 自動的に .rubocop_todo.yml から Cop supports --auto-correct. になってる Cop を拾ってきて PR 作ってくれるやつです。

ちょうど hey 社の CTO の藤村さんが同じ事をやっていてちょっとバズってたんですが、自分の gem 使ってほしかったなーと地味に思ってたりします。自分が世の中に対してアピールが足りてなさすぎましたね 😇

tech.hey.jp

何年か前に会社のブログで書いたりはしてたのでリンク貼っておく ✍

developer.feedforce.jp

Rubocop Challenger v2.3.0 をリリースしました 🚀

github.com

とはいえ新機能は一つだけで、 auto-correct された Cop が SafeAutocorrect かどうかを教えてくれる、というものです。

Add description whether the challenge is created by safe autocorrect or not by ryz310 · Pull Request #465 · ryz310/rubocop_challenger · GitHub

こんな感じの PR が作成されます。(画像は動作確認で作ったものなので、実際の Style/Alias は常に SafeAutocorrect: true になります)

Add description whether the challenge is created by safe autocorrect or not by ryz310 · Pull Request #465 · ryz310/rubocop_challenger Add description whether the challenge is created by safe autocorrect or not by ryz310 · Pull Request #465 · ryz310/rubocop_challenger

ぜひお試し下さい 👍

つぎやりたいこと

先日 GitHub が auto-merge 機能をリリースしましたね。自分は即全部のリポジトリで有効化しました ✅

github.blog

次やりたい機能としては 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.

また時間ある時にでも調べます。