p-hone p-hone.info

最も長い夜

とあるゲームでデータベースの作業ミスにより長期間ゲームが遊べない状態になっているという情報を見かけた。 そのゲームはプレイしてないが、それを見てふと昔のことを思い出した。 今はもうサービス終了したスマホ向けゲームの運用をしていた時代のことを。

過去記事でも度々触れているように、私は(ソーシャルゲームの)プログラマーで、 その時は期間限定イベントの実装を行ってリリースした後。 社内チャット経由で今回のイベントに重大な不具合があるらしいことを知った。 特定条件下においてイベントの報酬を多重に受け取れてしまうという不具合だった。

めちゃくちゃ焦った。自分が実装した箇所だから。 急いでソースコードを見返すと確かに報酬付与のあたりが怪しかった。 シンプルな正常系はテストできていたのだが、特定の条件でおかしくなる、そういったものだった。その時見返すまで気づけなかった。 しかし、誰がこの実装をしたかはチームの他のプログラマーなら知っているし、黙っていてもどうしようもない。 このとき私はまだ新卒だったが学生時代から多くのプログラムを書いてきた自負もあり、まさか自分が重大な不具合をやらかすことはないだろうと信じていたので相当なショックだった。頭がくらくらした。

しかし、もう終わりだ…と放心することは許されない。 今まさに不具合は発生し続けており、ゲーム世界のバランスが崩れる可能性すらある。 こんなのは想定外だった、とか言い訳をいくら考えても不具合は直らない。 よってチームの偉い人に伝える、「すみません、私の実装したイベントでこういう不具合がありました」。

こういった場合まずは何が起こるか、怒鳴られる……わけではない。 怒鳴っても不具合は直らないし、そんな暇はない。「わかった、まずは止血しよう」と言われる。 こうやっている間にも報酬は次々と多重にプレイヤーに配布されているのだから、まずは源を断つのが最優先というわけだ。 機能を止めるのは案外簡単だ、入口となる開始処理で固定のエラーを返すようにするだけでよい。 そして、報酬が多重に付与されないようにする修正も比較的すぐに入れることができた。

しかし、その後からが本当の地獄である。 すでに多くの報酬を多重に配布してしまっていた状況をそのまま見過ごすのは心象が悪い。 その不具合を利用したプレイヤーとそうでないプレイヤーに不公平が生じてしまうからだ。 よって、余分に配ってしまった報酬を回収する という計画が打ち立てられた。 最も長い夜が始まった。

言うのは簡単だが、余分に配った分を回収するのは簡単ではない。 ゲームの通常実装に「配り過ぎを回収する」なんて処理は存在しないし、誰に・何の報酬を・どれだけ・余分に配ったのか?という情報が必要になる。 つまり、「誰にどれだけ余分に配ったかを調査するプログラム」と「前者のプログラムで取得したデータの分だけプレイヤーから回収するプログラム」の2つをその場で即席で作らなければならない。

偉い人から他のプログラマー全員へこの不具合が告知され、今からみんなで回収作業だ!という流れに。 すでに17時を回っているタイミングで、サーバー側のコードを書けるプログラマー全員が居残り確定となってしまった。 自分のミスのせいで先輩プログラマー多数を巻き込んだということで心が痛む。 しかし、悲しみに浸っている暇もない、長引けば長引くほどプレイヤーから「バグで報酬を一部の人だけに多く配っておいて、このまま放置するのか!」と怒られてしまう。 とにかく急がなければ何もかも悪い方向に転がっていく、そんな状況だった。

まずは、誰が報酬を多重に受け取ったかを調査するプログラムからすでに難関だった。 受け取りを記録したログがあったのにそのログでは足りない情報があり、結局データベースの内部の更新履歴データを漁って該当するデータを掘り起こす作業・・・職人芸?みたいなコードを書くことになった。

そして報酬の回収も実装するわけだが、だが…………。 時刻はすでに22時を回っているような疲れ切った頭の状況、焦りもある中で果たしてこのコードを実行して一発で上手く動くのだろうか?という不安が大きすぎた。 その上、多数のユーザーの所持物を減らす処理というのはめちゃくちゃ怖い。間違えて他のアイテムを減らしてたら…?対象外のユーザーのものを減らしてたら……など考えるだけで恐ろしい。

しかし、とにかく急がなければならない状況なので即座に一緒に居残りしてくれている先輩にレビューをもらって回収を実行する。 Dry-run、目視、問題なさそう、Dry-runを外して実行。 これで長い夜は終わった……と思いきや、終わりではなかった。

形態が複雑なアイテムの考慮漏れがあり、一部のプレイヤーから本来回収すべき以上の量を回収してしまった疑惑が浮上した。 すると次はどうなるか? 回収しすぎた分を回収して再付与する という地獄の地獄がはじまる。 夜は更けていく・・・。

最終的にすべてが片付いた頃には午前3時を過ぎていた。 普段、なにか新しい機能を出したときはTwitterや2chでユーザーの反応を見たりするのだが、このときは本当に怖くて見れなかった。 どんな罵詈雑言が並んでいることだろう、とかそんな想像しかできなくてとても見られなかった。 でも、チームの同僚が見てたらしく「こんな深夜にまで対応してくれるなんてすごいって褒めてくれてますよ!」と言っていた。 それを聞いて当時は少しは救われた気持ちになって、はは…、深夜まで頑張った甲斐もあったもんだと思った。 (今振り返ると、残業や深夜労働を美徳とするのはまずくて、あまり喜ぶところではなかったなと思った)

それ以上に救いだったのは、同僚や上司が私を責めたりすることなく黙々と手伝ってくれたことだった。 内心はわからないが表では「ったく〜明日起きれるかなぁ〜明日午後出社でもいいですか?」と少し笑いながら朝方に帰っていった。 また、深夜に複雑な回収の処理を書かされているのに「面白くなってきたねぇ…!DBのログをどれだけ高速で掘る実装が書けるか競争しませんか?」なんて言ってその状況を楽しんでる節すらあって、これはカッコいいな……と感動したものだった。 そして、すべてが終わった後近くでラーメン食べようぜと連れて行ってくれた同期のプログラマーの優しさも沁みた。「いやー確かに大変だったけどこういう時にこそ勉強になるしな!」とポジティブな言葉で返してくれた。

この時の同僚・先輩方を見習って、私も、もし後輩がデカいやらかしを起こしても「面白くなってきたねぇ…!」の精神でやっていくぞ!と心に決めた ……のだが、運が良いのかあれからn年経った今、そういった状況に居合わせる機会はない。

オンラインゲームの大規模な不具合の後ろには必死に対応しているプログラマーやスタッフがいて、こういうことをやっているのかと 少しでも参考になれば幸いだ。自分はこういった経験を経てからは、障害発生の告知を見る度に怒りだとか呆れとかではなく、(裏方の人たち大丈夫かな…)と心配で心配で仕方なくなってしまうのだった。