ISUCON 10 完全敗北してきた

完敗だった 😇

何がまずかった?

自分の担当分について。

node.js の cluster 実装

今回、CPU が 2 core, 2 core, 4 core となっていたので、cluster 実装しないと golang のようにスコアがでない状況だった。
オンメモリキャッシュもしてなかったので、素直に src/bin で仮想ベンチと API をクラスター化したが、

  1. API とベンチを同じサーバで動かすなら、コア数 / 2 で fork しなきゃならないし、別々のサーバで動かすならコア数分 fork しなきゃならない
  2. コアを使い切っていると、TypeScript のビルドが固まる

という、とても微妙な状況だった。まぁ、結局サーバ 3 台を使い切るまで行かなくて、1 について懸念してたことは無駄だった訳だけど……。

WebPush の実装

マニュアルに、WebPush を実装すれば、ある API で空配列を返して良いと書いてあったんだけど、この実装がとても辛かった。

まず、マニュアルに書いてある通りに一度ベンチを回して isucon1 でログインしても、Push通知を受け取るボタンがブラウザ上に出てこないという現象に悩まされた。
しばらくマニュアルとにらめっこして、最終的に別サーバで試したら普通にブラウザ上に出てきて、だめだったサーバでも何度かベンチを回していたら突然出るようになった。これは結局最後まで原因が謎だった。

その後、無事サンプル実装は動かせて Push も受け取れて、大まかな実装も不慣れながらも 15:00 に大体完了したんだけど、そこから一切スコアがつかず、ずっと以下のエラーメッセージに悩まされていた。

webpush: 不正な Web Push メッセージの送信がありました (/push/...): illegal base64 data at input byte 27

原因は DB に突っ込む notification の型と WebPush のペイロードに突っ込む notification の型がぐちゃぐちゃになっていたことだった。DB の返す値に型が定義されてないなーまぁいっかーで進めてたのが非常にまずかった。

VSCode Remote

予選でほとんど問題なかったので最初はこれでやろうとしたんだけど、最初の方で 2 回 SSH が使えなくなり、こりゃだめだと諦めた。
これがかなりテンパってしまって、vim で書いたりローカルで書いたものを持ってったりと、慣れるのにかなり時間がかかった。次回は絶対ローカルで開発する。。

時間配分

講評がでないとわからないけど、上記の Push が無くても、もうちょいマシなスコアにすることはできたのかもしれなくて、どこかで諦める判断があっても良かった。

ただ、今回勝つにはおそらく Push をやっつけるしか無かっただろうから、勝とうとしたって目線だと、ここは悩ましい。

とはいえ 1 時間ごとにアラームならして「一旦手を引きましょう」とかしてもいいのかなと思った。

感想

問題自体はとても面白かったし、やりたいこともいっぱいある中でのタイムアップでとても悔しかった。。

来年も node.js で参加するかはかなり悩む。golang だったら cluster 実装は不要だし、WebPush 実装でハマることもなかっただろうし。うーむ、宿題だなー。

謝辞

出題者の皆様、今年の問題はテーマも含めとてもアガるもので、楽しかったです!
誤解のないように書くのですが、cluster と WebPush の notification 型問題のどちらも、nodejs の根本的な問題であり、参考実装自体には言語で差がつくような要素はありませんでした。
TypeScript の要望を聞いて頂いたおかげで、コードリーディングがとてもやりやすかったです!

また、運営の皆様、今年はオンライン開催で色々と大変だったかと思いますが、とても楽しい時間でした! ありがとうございました。へしこは日本酒とよく合います。ぜひ食べてみてください! またあいま賞!