こんにちは id:yutailang0119 です。
有志によって開催された株式会社はてな 社内ISUCONで、ISUCON11予選問題にSwiftで取り組んだレポートです。
amzn/smoke-framework を使ってチャレンジしました。
「ISUCON」は、LINE株式会社の商標または登録商標です。
株式会社はてな 社内ISUCON2022夏レギュレーション
- GitHub - isucon/isucon11-qualify: ISUCON11 予選 (ISUCONDITION) を解く
- ISUCON11 予選レギュレーション : ISUCON公式Blog に則る
- 本番と同じく、競技時間は 10:00 - 18:00 (JST) の8時間
- 社のAWSアカウントにインスタンスを用意
- 各チームはスコアをMackerelに投稿し、スコアを競う
チーム情報
- チーム名: チーム鈴木つば太郎
- メンバー
- id:yutailang0119
- 「Server-Side Swiftやるぞ!」と言い出した
- id:ikesyo
- チーム内だとAWSに明るい人材
- id:kouki_dan
- 巻き込まれた人
- id:yutailang0119
- 全員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フレームワーク
今回はAmazonのServer-Side Swiftフレームワーク Smokeを採用しました。
2022年現在のServer-Side Swiftというと、vapor/vaporを連想されますが、ISUCON11予選本番でVaporチャレンジをしたチームがいるので、あえて別フレームワークで取り組むことにしました。
結果
スコアはこちら!
最終スコアは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運営メンバーもありがとうございました!
*1:https://github.com/amzn/service-model-swift-code-generate/blob/a3eda1054e1e5599a24ffa70c5f595046f774334/Sources/OpenAPIServiceModel/CreateOpenAPIServiceModel.swift#L266-L304
id:yutailang0119
アプリケーションエンジニア。2018年中途入社。スマートフォンアプリ、特にiOSアプリ開発が得意。
Twitter: @yutailang0119
GitHub: yutailang0119
blog: がんばってなんか書く