株式会社はてな 社内ISUCONで、11予選問題のSwift Smoke移植チャレンジ #isucon

こんにちは id:yutailang0119 です。
有志によって開催された株式会社はてな 社内ISUCONで、ISUCON11予選問題にSwiftで取り組んだレポートです。
amzn/smoke-framework を使ってチャレンジしました。

ISUCON」は、LINE株式会社の商標または登録商標です。

株式会社はてな 社内ISUCON2022夏レギュレーション

チーム情報

  • チーム名: チーム鈴木つば太郎
  • メンバー
  • 全員iOSアプリ開発人材
    • ISUCON参加経験もなし
  • ゴール目標は "Swiftで最終スコア1点以上"
  • リポジトリは yutailang/isucon11-qualify

採用技術

参考実装がなく、Server-Side Swiftという未知の領域でもあるため、勘で進めました。
その中で、おもしろを優先した選択をしています。

ツールチェーン

実行環境はUbuntuのため、Swiftのインストールから行います。
今回は swift-5.6.2-RELEASE-ubuntu20.04.tar.gz.sig をインストールしました。

開発マシンは全員macOSのため、Xcode 13.4.1、Swift 5.6.1を使っています。
patchバージョンは異なりますが、大きな問題は起こりませんでした。

Webフレームワーク

github.com

今回はAmazonのServer-Side Swiftフレームワーク Smokeを採用しました。
2022年現在のServer-Side Swiftというと、vapor/vaporを連想されますが、ISUCON11予選本番でVaporチャレンジをしたチームがいるので、あえて別フレームワークで取り組むことにしました。

kateinoigakukun.hatenablog.com

SQLライブラリ

今回はVapor orgにある MySQLKit を使用しました。
理由は後述します。

github.com

結果

スコアはこちら!

スコア変遷

最終スコアは0点、Swift移植を時間内に終えることができませんでした🙃
多くの課題があったので、解説していきます。

Smokeの特徴と課題

Swift移植を進める上で、ISUCON11予選問題、あるいは標準的なWebアプリケーションの要件をSmokeで単純には実現できない箇所が見つかりました。

OpenAPIを基本とした設計

SmokeはOpenAPIと併用されることを強く意識した設計に見えます。
ISUCON11予選の問題にはOpenAPIのYAML定義は提供されていないため、SwiftでフルスクラッチにSmokeに必要なコードを実装するか、OpenAPI.yamlを定義してコード生成する必要がありました。

私たちは他言語の参考実装を見ながら、OpenAPI.yamlを定義することにしましたが、想像以上に大変な作業でした。

generatorの実装不足

OpenAPI.yamlからSmokeフレームワークで依存するamzn/smoke-framework-application-generateを通して、amzn/service-model-swift-code-generateでサーバー起動やエンドポイント毎の定義ファイルが生成されます。
このgeneratorはまだ Not implemented な部分が多く存在しているようです。
そのため、OpenAPIとしてvalidなYAMLを書いていても、コード生成での fatalError が多発しました。

具体的な課題点の一つは、JSONレスポンスボディのルートでarrayを返すことができないことでした。*1
回避案としては、アプリケーションでobjectで包んだレスポンス返しつつ、nginxでarrayにし直すなどでしょうか...

他にも、ISUCON11予選問題では、レスポンスとして画像を返すAPIがあります。
Content-Typeがimage/jpegに未対応のため、OpenAPI.yamlからのコード生成が失敗します。
これはアプリケーション以外で画像を返せるようにしないと、解決できなそうに感じます。

MySQLの想定がない

Smokeではamzn/smoke-dynamodbというDynamoDB向けライブラリはありますが、MySQLに対する言及を見つけることができませんでした。
レギュレーション上、MySQLの使用を指定されている訳ではありませんが、DynamoDBへの乗せ替えは制限時間とチームの技量として有効な手段とは思えなかったため、そのままMySQLを使うことにしました。
前述の MySQLKit を使用しましたが、組み込みと実行はできていそうです。

その他の未解決点
  • Cookieの取り扱い
  • JWTの実装
  • (Smokeに限った話題ではないが、) クロスコンパイルとデプロイ

初ISUCONを体験してみて

Swiftでの移植を目標としていたため、ISUCON本来の趣旨からは外れましたが、ISUCONを体験できて、より身近に感じられるようになりました。
毎年こんなにおもしろいことをやっていたのか、ともっと早く経験しておくとよかったと思います。

素振りの重要性

チーム全員がISUCON初挑戦だったため、事前準備のセーフラインの勘がない状況からのスタートでした。
今回は過去問題に取り組むため、うっかりネタバレを踏みかねず、事前準備での検索には気を遣いました。
最初はレギュレーションの在り処もわかっていなかったので、素振りは絶対に必要ですね。
個人的に、Vaporでの実装での素振りも計画中です。

メンバーの日常と違った一面を見れた

普段は3人ともスマートフォンアプリ開発をメインとし、主戦場はSwiftやKotlinです。
id:ikesyoがAWSインスタンス用意する姿は、普段とは違った一面を見ることができました。
id:yutailang0119 はNode.js、id:ikesyo はGo、id:kouki_dan はPythonと、3人それぞれが参考実装として読んでいる言語が違った点も、おもしろいポイントでした。

また、未知のフレームワークを目の前にした時、どこから探っていくのかにも個性が表れ、驚きや共感ポイントがありました。

おわりに

良問を作り続けているISUCON運営実行委員会を、改めて尊敬すると共に、感謝です。
(なお、ISUCON12では「はてなブックマーク」がメディア協力をさせていただきます!)
isucon.net

準備をしてくれた株式会社はてな 社内ISUCON運営メンバーもありがとうございました!