*「ISUCON」は、LINE株式会社の商標または登録商標です。
株式会社PR TIMES 執行役員CTOの@catatsuyこと金子です。
以前のブログで紹介したように弊社では社内ISUCON “TIMES-ISUCON”を開催しました。
今回はそんなTIMES-ISUCONに向けて元々5年前に作った社内ISUCONリポジトリの https://github.com/catatsuy/private-isu を復活させるために行った変更の一部を紹介します。
ちなみに私はこの社内ISUCONを作成した年にISUCON6本選の運営をし、その後にISUCON9予選の運営もしているISUCON大好き人間です。
Ruby実装
一部メンテナンスされなくなったGem (memcache-client) があったので別のGem (dalli) に変更し、依存するGemのupdateを行いました。
このリポジトリは元々Ruby実装が最初に作られて、他の実装はRuby実装から移植されています。一番重要な実装です。
フロントエンド実装
この問題のフロントエンド実装はほとんどないのですが、jQueryとjQuery Pluginが使われていました。2021年ということでpure JavaScriptの実装に変更しました。
なので今回参考実装に以下の変更が入っています。他の言語実装に移植していた方はこの変更をする必要があります。
- <script src="/js/jquery-2.2.0.js"></script>
- <script src="/js/jquery.timeago.js"></script>
- <script src="/js/jquery.timeago.ja.js"></script>
+ <script src="/js/timeago.min.js"></script>
Go実装
細かい変更を入れると色々あるのですが、抜粋して紹介します。
Go Modules対応
このリポジトリのGo実装では元々パッケージ管理を使用していませんでしたが、今回Go Modulesに対応しました。これによりGOPATH依存がなくなりました。
この問題と同じ年に作られたISUCON6本選ではMasterminds/glideが使われていました。どちらも私が作った実装ですが、当時はGoのパッケージ管理周りが定まっていなかった時代を感じます。
ちなみに本家ISUCONでは(こちらも元々私が作った実装ですが)ISUCON9予選のGo実装からGo Modulesが使われています。
http.StatusUnprocessableEntityを使用
参考実装ではCSRFトークンの検証エラーの時のステータスコードはRuby on Railsなどに合わせて422を返しています。元々のGo実装では定数を自前で定義していましたが、これを標準ライブラリの定数であるhttp.StatusUnprocessableEntity
を使用する用に変更しました。
これは忘れていたわけではなく、当時のGoのバージョンではまだ定数として定義されていませんでした。自前で定義する必要がなくなってよかったです。
SecureRandomの実装変更
Ruby実装でSecureRandom.hex
が使われている箇所をGoに移植するために自前の関数を用意していましたが、こちらは以前指摘してもらった実装に差し替えました。

ルーティングをzenazn/gojiからgoji.ioに変更
元々ルーティングに使用されていた https://github.com/zenazn/goji は https://goji.io/ に移行しているので、実装をこちらに変更しました。
参考実装だとユーザーページのURLに/@catatsuy
のような@
始まりでユーザー名を付与するルールで作っていましたが、こちらの実装が新しいgojiでは実装できなかったので諦めようかも思ったのですが、作者の方からinterfaceを使用する実装方法を教えてもらったので、それ通りに作ってみました。
ベンチマーカー(Go実装)
Goで実装されたベンチマーカーも少し変更しています。本当は一から書き直したいのですが、時間がかかりすぎるので今回は最低限の変更にとどめました。
Go Modules対応
参考実装同様、Go Modulesに対応しました。これによりリポジトリ自体がGOPATHに依存しなくなりました。
-tでschemaの指定を必須に
-t
オプションでベンチマークする先の指定をするのですが、今までhttp://
がなくてもhttp://
があると考えて実行するというよく分からない実装になっていました。わかりにくいのでschemaの指定を必須にしました。
ついでに今までHTTPにしか負荷をかけられなかったのですが、HTTPSでも負荷をかけられるようにしてみました。特に使用してないですが、多分動くと思います。
コマンドラインオプションを追加
-benchmark-timeout
と-wait-after-timeout
オプションを追加しました。開発用途などでベンチマーク実行時間を短くしたい時などに使用できます。指定しなければ変わらないので基本は無視で大丈夫なオプションです。
本当はやりたいができていない変更
私の知識量の問題でNode.js実装のupdate対応ができていません。なので今回Ansible上のNode.js実装のセットアップの処理はskipしました。
今回のセットアップではMySQLのバージョンが8になるため、Node.js実装を動かすためにはmy.cnfでdefault_authentication_plugin=mysql_native_password
という設定をする必要があります。動かせるようにするのは少し面倒かもしれません。
もしやる気がある方がいたらPRを送ってください。mergeするかもしれません。ちなみにここ数年のISUCONのNode.js実装はTypeScriptで実装されていますが、本実装はJavaScriptで実装されています。TypeScriptで実装し直しても大丈夫だと思います。
最後に
5年前に作った問題でしたが、割と2021年らしく生き返ったと思うので、もうしばらく楽しめる問題になったと思います。是非社内ISUCONやISUCONの練習にお使いください。使った際にはそのことをブログなどで発信してくれたらうれしいです。