@yuya_takeyama
- Software Engineer at Quipper
- Ruby/Rails
- JavaScript
- 活動
- ブログ: https://blog.yuyat.jp
- Twitter: @yuya_takeyama
- GitHub: @yuya-takeyama
- Creator of jr: jq like JSON processor for Rubyists
- Maintainer of woothee-php
今日の内容
- Quipper における Feature Flag
- 解決したかった問題
- Flagship の紹介
Feature Flag とは
- 個別の機能を On/Off するためのフラグの管理機構
- コード自体はマージしているが、リリースはまだしたくない、タイミングをコントロールしたい
- 一旦社内スタッフだけに有効化してテストしたい
- テスト環境でだけ有効化したい
Quipper における Feature Flag
- 教育プラットフォームをグローバルに展開
- フィリピン、インドネシア、メキシコ、日本、その他
- 一部マーケットごとに出したり隠したりしたい機能がある
- コンテンツの都合で、リリースタイミングが違ったりする
- 学年によって出しわけたかったりもする
- 例: 試験対策機能は小学生には出さない
QuipperSchoolとスタディサプリ
- Global: Quipper School
- 日本: スタディサプリ
- 基本的にソースは 1 つで、環境変数等で一部変えてデプロイしている
- アプリ・リポジトリとしては機能ごとに複数に分かれています (生徒向け・先生向け・コンテンツ制作者向け、等)
- それぞれごとの Feature Flag を管理する必要がある
これまでの実装
- 仕組みが複数あった
- YAML で静的に持っているもの
- たくさんの if 文で動的に持っているもの
- API 側の実装は ugly だが、クライアントサイドでは
user.hasFeature('foo')
みたいな感じでいい感じに取れる
- API 側の実装は ugly だが、クライアントサイドでは
- ひとつにまとめたかった
解決したかった問題
- 複数の Feature Flag のまとまりを管理する
- Ruby の DSL で宣言的に書きたい
- Ruby で書けるなら大体のことはできる
- それでいて設定ファイルっぽい感じにはしたい
- あと開発とかの都合で環境変数とかでサクッと On/Off できると便利そう
Flagship
定義
Flagship.define :quipperschool do
enable :a_stable_feature
enable :an_experimental_feature, if: -> {
context.current_user.staff?
}
disable :deprecated_feature
end
Flagship.define :studysapuri do
# ...
end
# before_action の中とかで
Flagship.select_flagset(:quipperschool)
分岐
単純に if 文
if Flagship.enabled?(:an_experimental_feature)
# ---
end
コンテキスト変数
動的な判定を行う時に必要な値をセットしておける。
# 値をセットする
Flagship.set_context :current_user, current_user
# メソッドをセットすることもできる
Flagship.set_context :current_user, method(:current_user)
# それを使った定義 (先のスライドにも出てましたが)
Flagship.define :quipperschool do
enable :an_experimental_feature, if: -> {
context.current_user.staff?
}
end
環境変数による On/Off
-
FLAGSHIP_***
という変数にtrue
/false
を指定すると強制的に上書きできる - コードのデプロイとは別のタイミングでリリースをタイミングできる
その他の機能
- タグ (メタデータによる機能の分類)
- API からある機能群の On/Off をまとめて返したいときとかに使う
- ヘルパーメソッド
- フラグの定義に必要な処理を DSL 内で共通化できる
- 継承
- 本番と開発環境で微妙に違う、みたいな時にベースの定義から継承できる
稼働実績
- Quipper School では先々週ぐらいから Flagship で機能がひとつ ship された
- スタディサプリではちょうど今日 (!) 機能がひとつ ship された
- 機能のやり方 (YAML とか) からの移行は徐々にやっていく
今後やりたいこと
- 一部ユーザ (全体の 10% とか) のみへのリリース、とかも必要そうになれば
- いわゆるカナリアリリース