こんにちは!エンジニアのkanekoです。
私はタイムゾーンの考慮に毎回苦戦しています。
そして、最近やらかしが発覚したので反省を書きます。
プロローグ:サービスのデフォルトタイムゾーン
私はいこーよで買えるWEBチケットの商品取り扱いプロダクトの開発を担当しています。
このプロダクトでのタイムゾーン はこのようになっています。
タイムゾーン | |
---|---|
アプリケーション | UTC |
データベース | UTC |
サーバー | JST |
アプリケーションもUTCです。これが私は毎回辛い。ここは日本。ここは日本なんだ。
第1章:土日祝日だけ監視したい
いこーよのユーザーさんは、週末にいく先のチケットをお出かけ先が決まったら購入し利用される方が多い傾向があります。 一方、会社として基本は暦通りの営業日なので土日はおやすみです。*1
そこで、サービス開始*2から間も無く、「会社が休みの土日祝日だけデータをチェックする」というバッチジョブを作ることになりました。 そこにアサインしたのはこの私。
私「何時に、どれくらいの頻度でやります?」
ディレクター「深夜帯はアクティブな人が少ないし朝6:00から3時間おきにしよう」
私「わかりました!任せてください!」
そして、データをチェックしておかしければ通知を飛ばすようにしこのようなコードを書きました。
require 'holiday_jp' (略) def call current_time = Time.zone.now today = current_time.to_date return unless weekend_or_holiday?(today) (略) end private def weekend_or_holiday?(today) today.saturday? || today.sunday? || HolidayJp.holiday?(today) end
勘が良い方ならお分かりですね。
第2章:そして発覚の時
ある土曜日の朝9時、このバッチによる通知が飛んできました。 その時は結構な自体だったので、対応可能なメンバーで
「商品落とします」
「私はこれを確認します」
「影響範囲を調べます」
「関係者に連絡します」
という感じで対処を最優先に動きました。
後日、振り返りのミーティングがありました。
冷静なエンジニア「状況を踏まえると朝6時に通知来てないのおかしくないですか?」
私(えっ)
人々「本当だ。後3時間早く気づけたかもしれない」
第3章:一体なぜこんなことに
土曜の朝6時にサーバー自体はJSTなのでジョブ自体は実行されていました。
しかし、アプリケーションはUTCなので、current_time = Time.zone.now
の戻り値はUTCの時刻です。
2020/02/01 6:00 に実行(土曜日)したとすると
require 'holiday_jp' (略) def call current_time = Time.zone.now # => 2020-01-31 21:00, today = current_time.to_date # => 2020-01-31 return unless weekend_or_holiday?(today) # ここでreturnして終了!!!!! (略) end private def weekend_or_holiday?(today) # => false today.saturday? || today.sunday? || HolidayJp.holiday?(today) end
となります。
ちなみにテストは書いていましたが、テストではこの事象には気づけませんでした。
プロローグ: それでも生きていく
「改めて振り返るととてもとてもとても単純なことなのに、どうして気づけなかったの・・・」と思うばかり。
私がタイムゾーン に弱いばっかりに検知が遅くなってしまったことは本当に申し訳なく思います。 でもこれを機にいくつかの記事を参考に読んだり、考え方を質問したりして、少ーし成長できたような気もします。 今後は同じ原因で何かの過ちをうみ出さぬよう、時の扱いには細心の注意を払ってコードを書いくぞと心に固く誓っている次第です。
後書き
以上、私の個人的な失敗と誓いの表明でした!
今回は、社内の人が「エンジニアじゃなくてもわかるように書いてよ」って以前言っていたのを思い出して仕立ててみました。 いかがだったでしょうか。
さて、アクトインディでは共に働く仲間を大募集しています。 共に時を超えていきたい方はぜひご連絡ください!