Uberが新たにオープンソースとして公開したPiranhaは、Java、Objective-C、Swiftで記述されたAndroidおよびiOS用のモバイルアプリから無効なコードを削除するためのツールだ。実装した機能フラグ(feature flag)を最終的に削除する、というプロセスから生じる技術的負債を確実に解消する目的でこのツールは誕生した、とUberは述べている。
機能フラグは、新しい機能を試すための優れた方法だ。機能フラグを使えば、新機能をコントロールしながらロールアウトしたり、ユーザ毎に異なるバリエーションの新機能をロールアウトして、それぞれの評価を確かめたりすることが可能になる。バグの確認された新機能や、ユーザベースに受け入れられなかった新機能を迅速にロールバックすることもできる。
あまり論じられない機能フラグの重要な側面のひとつとして、UberのエンジニアであるMurali Krishna Ramanathan氏が説明するのが、その技術的負債(Technical Debt)だ。機能フラグが広範に使われることが、非常に大きな技術的負債になる可能性がある。技術的負債の問題は、機能フラグがその役目を終える頃に顕在化する。その理由は、段階的なロールアウトの完了、あるいは機能の全面的なキャンセルなどだ。機能フラグが不要になれば、それを実装したコードだけでなく、フラグが取り除かれたことで到達不能になったコードも、すべてクリーンアップする必要がある。
コードをリファクタして不要なフラグによる技術的負債を取り除く作業は、予想以上に大変なものになる場合があります。私たちの経験から言えば、これはさまざまな問題が重なることよるものです。
- フラグの不要性に関する情報をあいまいにする、最善ではないフラグ管理、
- フラグのオーナシップに影響する組織の撹乱、
- フラグ関連のソースコードをクリーンアップする作業に対する開発者の意欲の欠如、など。
Uberのエンジニアたちは、複数のアプリにわたって6,000以上のフラグを管理するようになっていたので、不要になったフラグに関わるコードのクリーンアップに時間を費やすのは、新たなフラグを実装する作業の障害になる可能性があった、とRamanathan氏は説明を加えている。
Piranhaは抽象構文木(AST)のレベルで動作し、機能フラグに関連するさまざまな共通パターンを検出する。コード内から機能フラグを識別する作業は、特別なアノテーションの使用に基づいて行われる。また、不要コードをクリーンアップするプロセスは、フラグ管理システムによって完全に自動化されている。エンジニアのプロセスを合理的にするため、Piranhaは、フラグ管理システムに対して不要になったフラグの問い合わせを定期的に実行し、取得した差分をレビューするためにフラグのオーナに送信する。
Uberの調査によると、Piranhaの生成した差分の75パーセント以上がエンジニアによって効果的に処理されている。奇妙なのは、Objectve-Cの差分の約95パーセント、Swiftの差分の75パーセントが処理されているのに対して、Javaの差分は55パーセント程度に過ぎないことだ。これは、Swiftやobjective-Cの差分に比較して、Piranhaの生成するJavaの差分には手作業での処理が必要な部分が多い、という事実によって説明できる可能性がある。さらには、App Storeのネットワーク(over-the-air)アップデートにおけるサイズ要件が他より厳しいことも、iOSエンジニアに自身のアプリのバイナリサイズを削減するモチベーションを加えている。同じように、Piranhaが生成する差分が継続的インテグレーションのテストをパスする割合も言語によってさまざまで、Objective-Cではほぼすべて(99.41パーセント)であるのに対して、Javaは最低(71.46パーセント)になっている。
Piranhaは不要になったフラグの問題に対する完璧なソリューションではなく改善の余地がある、と開発者たちは述べているが、Uberのエンジニアの間においては、フラグの技術的負債を返済するプロセスの自動化において効果的であることが証明されている。