どうでも良い前書き
僕は過去のプロジェクトで toB 向けの業務システムを作っていました。
何が言いたいかというと、たまたまですが、ユーザーは深夜には業務時間外でアプリを触らないのです。
最近は toC 向けのアプリを作っているのですが、バッチ処理のタイミングについて学びがあったので共有します。
今回の話は、僕が直面した問題を別の例えで説明するものです。
バッチ処理のタイミングは仕様等さまざまを考慮して設定しよう
アプリ内で、ユーザーがシーズンごとに特定の期間内で順位を競う「ランキング機能」があるとします。
ランキングには有効期限があり、期限を迎えるとランキングはリセットされ、新しいシーズンが始まる設計です。
ここでは、ランキング情報はユーザーテーブルに保持していると仮定しましょう。
ユーザーとしては、期限日の0時を過ぎたらランキングがリセットされていることを期待するはずです。
しかし、ランキングリセットのバッチ処理が3時に実行されていたらどうでしょうか?
toBアプリなら問題ないかもしれませんが、toCアプリでは深夜にもアプリを使用するユーザーがいます。
そのようなユーザーが期限日の0時過ぎにバグを発見するのです。
「0時を過ぎたのに前のランキングが表示されている!」
正直この例は、アプリ設計が適切なら回避できたとも言えます。
ただ、アプリ設計が不完全だったとしても、0時にバッチ処理を走らせていれば防げたかもしれないという話です。
つまり、バッチ処理のタイミングも、ユーザー体験に直結する重要な要素だと僕は考えています。
バッチ処理のタイミングは、しっかり仕様や様々なものを考慮しようということです。
バッチのスケジュールはアプリ側で行うと良さそう
ランキング更新バッチがサーバーのcronで管理されていて、ちょっと厄介なことに出会いました。
アプリ側のコードにはタイミングの記述がないため、開発者は「0時に実行されているはず」と思い込んでしまいます。 (僕がそうでした。)
しかし、ユーザーにバグを報告されるとか、コードリーディング時に不思議に思ったりとか、何らかの理由で調査のためにサーバーに入って crontab -l
を実行すると、「バッチ処理が3時に設定されてる...」と驚くわけです。
このような問題を回避するためには、以下のような対策が有効だと考えています。
- バッチ処理を アプリ側でスケジュール管理する
たとえば Rails であれば:
-
whenever
を使えば、cron をアプリから管理できます -
good_job
のようなジョブキューを使えば、柔軟なスケジューリングも可能です
PHP はまだ書き始めたばかりなので、同様の仕組みがあるのかは今後調べなきゃ...。
まとめ
今後バッチ処理のタイミングを考える時は、僕ももっと慎重になると思います。
- バッチ処理のタイミングは、ユーザーの行動時間、仕様等さまざまを考慮しましょう
- バッチ処理はアプリケーションのコードで管理しましょう
- IaCでcronを設定するのも良いかもしれません