トレタ開発者ブログ

飲食店向け予約/顧客台帳サービス「トレタ」、モバイルオーダー「トレタO/X」などを運営するトレタの開発メンバーによるブログです。

FaradayのClientErrorに苦しんだ話

こんばんは。配達依存症がさっぱり治らないサーバサイドエンジニアの佐藤です。 この記事はトレタ Advent Calendar 2019の三日目です。

FaradayというHTTP クライアントライブラリ

みなさんRubyのFaradayというHTTP クライアントライブラリをご存知ですか? Faradayを使えば外部のAPIと接続するクライアントを楽に記述することができます。ミドルウェアを差し込むことでリクエストやレスポンスをいじったり覗いたりすることができ、JSONに変換したい、アクセストークンを乗せたい、細かいログを取りたい、と言ったことを一箇所にまとめて記述することができます。いろいろできて便利なのですが、今日はその中でも raise_error middleware という特定のステータスコードが返ってきた時例外を出してくれるミドルウェアに苦しんだ話を書きます。

raise_error middleware と retry middleware

raise_error middleware は400や404と言ったClientErrorや500のようなServerErrorのステータスコードが返ってきた時に、それに応じた例外を出してくれます。これによってステータスコードを確認して処理を抜けるようなコードを書いたりする必要もなくrubyの例外処理を使って様々なErrorに対応することができます。

これとよく組み合わせて利用されるのが retry middleware です。 retryはその名前の通り特定の例外や条件においてリクエストを自動でリトライさせることができます。例外がトリガーにできるため、上記raise_errorと組み合わせることでタイムアウトしてしまったらとりあえずもう一度やり直す、のような処理をmiddlewareの設定のみで行うことができるようになります。

raise_errorがraiseするもの

さてここまで揃えば話は単純で、raise_errorが上げてくれる諸々の例外に合わせて必要なretry設定をretry middlewareでしてあげれば良い。そう思っていました。 ところがこれ、実際にやってみると faraday (0.17.1) (執筆時最新バージョン)では期待通りに動作しません。なぜなら、404,407を除く400〜600は全てClientErrorが吐かれるからです。 (該当のソースコードはこちら

これ最初知らなくてハマりました。よく出会うであろう404はちゃんと専用の Faraday::ResourceNotFound が返ってくるんです。他の4xxが Faraday::ClientError なのはわかるとして、5xxまでClientErrorだったのは最初全くの想定外で、そうだと理解できるまで結構な時間を費やしました。

ちなみに Faraday:: ServerError ですが、ステータスコードが取得できないケース(ServerError)やタイムアウト時(TimeoutError)に出てきます。

5xxでリトライしてもらうには(4xxでリトライしないためには)

幸いなことにretry middlewareには retry_if という条件を指定してリトライさせる機能があります。こちらを利用してClientErrorの中からさらに4xx以外の時にのみretryさせることができるようになります。ちょっと本末転倒感はあるんですが、それでもfaradayとmiddlewareの設定で完結させることができるために、見通しはよくなる気がします。

サンプルコード

conn = Faraday.new(:url => 'http://example.com') do |faraday|
  faraday.request   :retry,
    methods: [], # retry_ifを無視してリトライするHTTP methods。無視して欲しく無いのでemptyにする
    exceptions: [Faraday::Error::TimeoutError, Faraday::Error::ConnectionFailed, Faraday::Error::ClientError],
    retry_if: ->(env, _exception) { !(400..499).include?(env.status) } # status codeの4xx以外ならリトライ
  faraday.response :raise_error
  faraday.adapter Faraday.default_adapter
end

補足:次のバージョンで直るらしい

faradayのmasterブランチを見にいくと、ServerErrorがちゃんとだし分けられています。faradayはv0.x、つまりまだ開発版なのでv1.0.0のリリースで書き換わるのでしょう。その際のバージョンアップでは注意が必要です。

余談ですが、0.16.2の時に一瞬このServerErrorへの変更がお漏らしして、必死こいて対応してました。ようやく修正が終わって、その苦労をblogにしてやろう・・・と思った矢先に0.17でロールバックされてしまったので、本記事はその供養も兼ねています。


今年のトレタのアドベントカレンダーはこちら!

qiita.com

テックトークという社内勉強会をやっています

こんにちは!ポケモン剣盾のランクバトルでようやくスーパーボール級になったサーバサイドエンジニアの川又です。

いまの環境はミミッキュとドラパルトがとても多くて、対策をどうしようかと悩んでいます。。。

今回は、テックトークという毎週行っている社内勉強会について紹介します!

トレタのプロダクト開発 / toreta tech talk#2 - Speaker Deck

↑のスライドにも書いてあるのですが、トレタで開発しているメインのサーバサイドのシステムはフレームワークはRailsを採用しているのですが、Rails以外にもSidekiqなどのライブラリも多く使用しています。

サーバサイドのシステムを開発するにあたって、予約の管理などのトレタ特有のドメイン知識については、資料を読んだり人に聞いたりすることで勉強することができるのですが、RailsやSidekiqなどライブラリそのものについては勉強するような機会が用意できていませんでした。

そのため、まずは「コードリーディング会」という名前でライブラリについての勉強会をやってみることにしました。

担当者は題材について事前に勉強してきて、当日はコードを読んだり実際に動かしてみたりして題材について紹介して参加者みんなで議論して、esaにログを残しておく、というものになります。

switch_pointや、SidekiqArproxyOpenStructなど、トレタがお世話になっているライブラリについてのコードリーディングを行ってみました。

最初はサーバサイドのエンジニアが多めだったのですが、嬉しいことにiOSエンジニアやフロントエンジニアの方々も徐々に参加してくれるようになり、RubyやRailsだけでなくSwiftやGoのライブラリ・社内システムの勉強をすることもできるようになってきました。 また、「コードリーディング会」という名前ではあったものの、実際にコードリーディングだけをするわけではなく、社内システムの紹介だったり、HTTP2やgRPCの紹介をしてくれる回もありました。

最初はサーバサイドエンジニアメインでコードリーディングをしてみようというつもりで初めてしまったものの、コードリーディングにとどまらず、またサーバサイドエンジニアだけにとどまらず、さまざまなロールのエンジニアが参加する勉強会に発展してくれたので、今後は「 テックトーク 」という名前で引き続きやっていきます💪💪💪


ちなみに、今年もトレタの開発に関わっている方々によるアドベントカレンダーをやっています 🎁

qiita.com

みんなが思い思いのいろいろなテーマで書いてくれると思うので、ぜひ見てみてください!

builderscon tokyo 2019に行ってきました

こんにちは!サーバーサイドエンジニアの川村です。
8/29(金)〜31(日)に行われたbuilderscon tokyo 2019に行ってきたので、(気づいたら丸1ヶ月経ってしまいましたが)その感想を書いていきます。

builderscon?

buildersconは、「知らなかった、を聞く」をテーマとした技術を愛する全てのギーク達のお祭りです

公式サイトより

言語などの縛りなしに技術で色々やってみた話をきく会となっており、色々な方向性の話があって楽しいカンファレンスでした。
今回、トレタは懇親会スポンサーとなっており、↓の2つのカクテルを提供させて頂きました。
(会場では手違いで名前が逆になっていたのは内緒です)

f:id:yosinani4472:20191002163906j:plain toreta on rails

f:id:yosinani4472:20191002163914j:plain toreta on kubernetes

私は所用で懇親会に出れなかったのでどんな感じの味だったのか分からないのですが、楽しんでいただけていたら嬉しいです!

印象的なセッション

今回聞いたセッションの中で特に印象に残っている3つについて紹介します。

8/30 13:20〜 コンパイラをつくってみよう

goでコンパイラをライブコーディングするセッション。

1時間の講演時間中に四則演算のコンパイルができるようにすることを目標に、 標準入力からソースを受け取ってgccで実行できるアセンブリを出力、パイプで渡して実行してみるという内容でした。

10回以上リハーサルを重ねただけあり、コーディングのスピードもすさまじく、バグったときに会場のいろんな人がどこが間違ってるかその場で指摘していく暖かみもいままでに見たことが無い光景で非常に印象的でした。

動画が公開されたらぜひ見て欲しいセッションです。

8/31 13:00〜 スーパーカミオカンデの開発と運用

ニュートリノ検出の実験装置、スーパーカミオカンデを構築・運用していく際の苦労などについてのセッション。

例えば、

  • 1万本のセンサー(光電子増倍管)から全く同時に値を受け取らないといけないが、ケーブルの長さが少し違うだけでタイミングがずれるので位置に関係なく全てのケーブルの長さが同じになっている

  • 大量のデータを送信する2GBごとに100Byte単位でデータがいれかわるのでハードウェア選定が大変だった(昔の話)

など、自分では一生原因に気づけなさそうな問題について話されていて、同じ「システム開発」という括りでも分野が違えば求められるものも全然違うんだなと感じました。

8/31 15:20〜 もしもハッカーの「サイバー攻撃日誌」が読めたら

登壇者さんが普段、業務としてやられているサイバー攻撃の具体例のセッション。

フィッシングメールやエクセルのマクロの危険性など、普段なんとなく聞いて知っているサイバー攻撃が実際どう使われて、最終的にどうなるかというのがリアルに分かって非常に面白いと同時に恐ろしくなりました。

エクセルのマクロからなんて大した攻撃できないのでは?と思ってましたが認識を改めました...。

全体的な感想

特定技術のカンファレンスでは出てこないような話が多く、来年もまたぜひ参加したいと思います!
「技術」というワードに対して多角的にセッションが配置されており、ITエンジニアと呼ばれる人はだいたい何か楽しめる要素があると思うのでこれを読まれた方もぜひ参加してみてください!

© Toreta, Inc.

Powered by Hatena Blog