元々3台構成で Android CI を運用していましたが、日中開発が活発な時間帯に多くのジョブが同じタイミングで実行されてしまうと、高頻度で CI が詰まってしまうことがありました。
ジョブ単体でみればそのほとんどが実行時間が10分前後のものばかりなので、キューが詰まったとしても何時間も待つことはありませんが、CI 実行を多少なりとも待つ場面を何度観測しました。
上述した料金は Android CI 環境全体のコストであり、今回はクックパッドアプリの CI 環境のみを移行した段階における内容なので、まだ全体のコストの比較が可能な段階ではないので具体的な値を記述することができません。
しかし大雑把にコストを見積もった限りでは、コストを約1/6に抑えることができるようになる予定です(あくまで予定です)。
また Genymotion Cloud に変わる Firebase Test Lab については、実行数制限がない Blaze プランで実機デバイスでも $5/hour という価格帯なので、Genymotion Cloud と比較すると雀の涙程度の料金となっています。
(参考としてクックパッド Android アプリの Instrument Test は1回10分未満程度で実行可能です)
Google Play Service を CI 環境でも利用したい(主にテストが書きたい等)という要望があがり始めていたので、今回の CI 環境移行のタイミングで改善することとなりました。
また CodeBuild の実行状況に合わせて柔軟にスケールが可能であり、かつ CodeBuild からできるだけ容易に接続できるかという点を考慮しました。
さらに特定のスペックの端末でテストを実行したいというような要望も合わせて検討しました。
現在 Android 実行環境を提供しているマネージドサービスはたくさん存在しています。
AWS にも DeviceFarm という機能がありますが、プロビジョニング時間や端末のバラエティ、またエミュレータが利用できない等のいくつかの理由から利用を諦めました。
Bitrise や Circle CIなどの環境も考慮しましたが、AWS 上に構築された社内リソースをうまく活用できるという点からも CodeBuild を採用したので、これにうまく組み合わせることができる Firebase Test Labを採用しました。
Firebase Test Lab では実機とエミュレータの2種類から実行環境を選択でき、エミュレータを選択することでデバイスの空き状況を気にせずに並列実行を行うことができ、また Google Play Service が利用可能なデバイスを利用であり、かつ Google が提供するサービスというのが大きな決め手となりました。
以前から Test Lab の RoboTestを利用しており、その延長線で Instrument Test の実行も Test Lab に移したという面もあります。
クックパッドではもともと、個人に割り当てられた PC の持ち出しをほとんどの場合において許可しています 。持ち出しにあたっては、パスワードの設定などはもちろんのこと、内蔵記憶領域の暗号化など必要な設定が必ず行われるようになっています。
MDM (Mobile Device Management) として Microsoft Intune や Jamf Pro を利用し、管理を行っています。
PC 上のイベントは EDR (Endpoint Detection and Response) 製品を利用して監視やイベント対応を行っています。現在は主に CrowdStrike Falcon を利用しています。
また、特に機微な情報に触れるようなケースでは、VDI (仮想デスクトップ環境) として Amazon WorkSpaces を利用し、クライアント PC から接続して利用するようにしています。
PC 内蔵のマイクでは、キータイプ音が混じったり音をうまく拾わなかったりなど、長時間の会議には不向きなことがわかっていました。特に、イヤホン・ヘッドホンなど声を聴くためのデバイスは分離しておいたほうが良いようです。
そのため、外付けマイクやヘッドホンをお持ちでない方には以下のような対応を推奨しています。
答えは様々です。「M 個分」や「M 枚分」、「M 皿分」のように「人」ではない助数詞による表記もあれば、「M cm タルト型」や「直径 M cm シフォン型」、「M cm 丸形 L 個」のように何らかの型の大きさとその個数による表記もあります。
こういった分量を「N 人分」に換算するにはどうすれば良いのでしょうか。同じ「M 個分」でもマフィンのレシピとケーキのレシピで N は違うでしょう。また、M は全角の時も半角の時も漢数字の時もあります。接頭辞や接尾辞も付いたり付かなかったりします。さて、どうすれば良いのでしょうか。
人手で頑張る
やっぱりまずはこれでしょう。人間の能力はすごいです。どんな表記でもちゃんとパースして、常識的な N に換算することができます。悩んだ時もレシピのタイトルや完成写真、各材料の分量などを参考にして、違和感のない N を選択することができます。
実際、1 日に十数レシピ(1 年で数千レシピ)の分量が人手で「N 人分」に換算されています。これは、配信記事で取り上げるレシピのカロリーを計算する過程などで換算されるものです。換算の際は、まず、一人のアノテーターが仮の N を決定します。そして、別のアノテーターがチェックして、最終的な N を決定します。
なお、チェック時のアノテーター間の一致率は大体 67% です。また、残りの 33% もそれほど大きな違いがないケース(e.g., 一人が N = 3、もう一人が N = 4)が多いです。これは、そもそも N の候補が少ないことが幸いしています。クックパッドのレシピは家庭用のものが多いので、大体 75% のレシピで N は 1 〜 4 です。
意外だったのは、分量の情報のみを使用した single-source model の正解率が multi-source model の正解率より高かったことです。本質的には、タイトルの情報を使用せずに N を推定するのは不可能です。上でも言及したように、同じ「M 個分」でもタイトルが「マフィン」のレシピと「ケーキ」のレシピで N は違うでしょう。
single-source model が multi-source model に勝利(その差は 1% ですが)した理由はおそらく二つあります。一つ目は分量の情報のみでも、ある程度は、人数分が推定できたことです。ベースラインの正解率が 47% だったことから、47% のデータは「M 個分」などの M がそのまま正解の N だったことが分かります。こういった場合はタイトルの情報が必要なかったのかもしれません。
もう一つは、単に、multi-source model がタイトルの情報をうまく利用できなかった可能性があるということです。ベースラインで対応できなかった 53% のデータではタイトルの情報が有用に思われます。しかし、今回の実験では、二つのエンコーダーを学習させるには訓練データが少なかったのかもしれません。
以上を踏まえて、今は single-source model を試用しつつ、multi-source model を改善しているところです。訓練データを追加していけばどこかで multi-source model が勝利するのではないかなと予想しています。
タイトル
分量
正解
single
multi
素朴なレーズンパン
1 斤
8
8
8
ツナポテトのミニコロッケ☆お弁当にも
8 個分
4
8
4
甘さ控えめのクッキー
鉄板 1 枚分
16
10
10
最後に成功例と失敗例を紹介します。一つ目の例は single-source model と multi-source model の両方が正解しました。「1 斤」を「8 人分」と換算したのはなかなか面白いです。二つ目の例は multi-source model だけが正解しました。「ミニコロッケ」は「2 個分」で「1 人分」と学習してくれたのでしょうか。三つ目の例は両方とも不正解でした。この場合、材料欄の情報(e.g., 各材料の分量)も利用しなければ正解するのは難しそうです。この辺りも今後の課題です。
低コスト運用:「横断的に複数のデータソースを使ってアラートの精度を上げる」といったアプローチは新しいものではなく、昔からSIEM(Security Information & Event Manager)でも同じような取り組みがされていました。しかし、多くのSIEMはリアルタイムにイベントを処理するような設計となっているため高い処理能力が求められ、高価になってしまう傾向があります。もちろんお金で解決すべきところにはお金を投入するべきですが、セキュリティは直接的にビジネスに貢献するものではないこともあり、工夫次第でコストを抑えられるならそうするべきと考えました。
先述したとおり、Reviewerは調査で集められたアラートの情報をもとに、そのアラートが実際の被害を及ぼしたのかを評価します。評価の方法や仕組みは Lambda Function にコードとして自由に記述できるようにしました。現在、クックパッド内ではGo言語を使ってポリシーを記述していますが、DeepAlert側で規定した Lambda Function に対する入力と出力のインターフェースに則っていればどのような言語で記述できます。
まず alertsがセキュリティ監視・防御システムから発報されたアラートになります。このアラートについても独自のフォーマットになっているため、発報するシステムとDeepAlertの間で1つLambdaを挟んでフォーマットの変換をしています。attributesの部分にはそのアラートに出現した属性値になります。それぞれIPアドレスやユーザ名といった型を付けているのは従来のSIEMなどと同じですが、 contextというフィールドをもたせることでその属性値の意味がわかるようにしています。これは、例えば「Source IP address」という型でアラートの属性値が正規化されていたとしても、それが内部と外部のどちらのネットワークを意味するのかであったり、何か攻撃をした側なのか、それとも攻撃を受けた側なのかということが発報時の文脈によって変わってしまうという問題に対応するための説明用フィールドとなっています。
Hello there, it's Dave Fox! I'm an iOS engineer from the Creation Development department in Cookpad. (@wowitzdave)
In this post, I'm going to talk a bit about how I used custom internal tooling and prototyping tools to help Cookpad's design and development workflow.
I'll look at how product and engineering teams can interact with each other more efficiently and ways in which we, as engineers, can empower designers to make their visions become a reality more easily.
Introduction
Last year, I began work on the internal Cookpad iOS renewal project. As part of its development, I was responsible for creating a new UI component to display user images in a style known as the Ken Burns effect.
The effect consists of panning and zooming around images and cross-fading between each one to give a sense of depth and dynamism.
Here's a short look at it in the iOS Cookpad app today...
Technical Implementation
Looking at the above effect, it doesn't seem too complex to implement... Just display some images with a zoom or a pan and fade between them. However, there are many settings and attributes applied to each image's animations and also to the slideshow's root animation as a whole. Each and every one of these values needs to be carefully considered to create the right "feel". Let's take a look at the parameters our animation requires:
For The Overall Slideshow
How long (in seconds) should we show each image?
How long (in seconds) should the duration of the cross fade be?
Additionally, each image uses either a zoom or a panning animation. These styles also have individual settings...
For Panning Images
From which anchor points should the animation start from and end at?
What speed should the animation happen at?
For Zooming Images
At which anchor point in the image should we zoom from?
What scale should we zoom from and to?
What speed should the animation happen at?
In order to create the exact effect the product team wants, these are all parameters the designers want to be able to define.
In a feature like this, it is often difficult for designers to imagine exactly what values they want. Often, design and development will work on a "trial and error" basis, tweaking values back and forth. With this many settings though, it would take a lot of time from two people to achieve the final goal. The workflow may look something like this:
The issue with this flow is the "Cross-department communication" bottleneck. Because of rapid iteration, this happens frequently and takes the time of both engineering and design teams to communicate changes. Each iteration takes a lot of time and disturbs the working pattern of all members involved on a feature.
A Product-Centric and Tools-Driven Approach
I had a lot of other tasks to work on as part of the renewal project but I knew the product team would want to iterate on this feature a lot so I decided I wanted to create a workflow which could reduce friction between design and engineering, keep both sides as productive as possible and, at the same time, create a toolset that is easy to use and familiar to designers. This was important to enable design to be as creative as possible.
Giving Designers Greater Control
To achieve this workflow, I decided to make a testbed application that would allow the design team to reiterate and play with all these animation values.
Then, when they were satisfied with the final animation. I could simply take their finalised values and copy them into the main iOS app codebase.
This would make the following workflow possible:
Designers perform both the review and adjustment stages
Testbed Application Implementation
So, I started off with a basic implementation of the Ken Burns effect with some default values and then created a simple application with screens to alter the animation settings and view a live preview of how the animation would look in the final product.
Let’s take a look at what this app ended up looking like:
Overall Settings
Zoom Settings
Pan Settings
Overall animation settings
Zoom scale and anchor point settings
Pan from and to anchor point settings
As the design team modifies the animation values, they can preview their settings at any time on the home screen. This screen shows the animation in a number of different sizes and aspect ratios so the designers can see how things will look in a variety of different contexts within the Cookpad iOS application:
The designers can quickly and easily play with these values and, once happy, I have one sit-down meeting with them and integrate their final values into the application.
Results
When I think of the merits of this kind of approach to feature development, I look at two main areas:
Engineering time and effort
Friction between the wants of designers and the final output of engineering.
Time Taken
The design team made many many iterations of these values within the testbed application but because they could iterate in isolation, I didn’t need to spend any of my time on each change. With the "one time integration" approach, bringing the product team's vision into the main app only took me about 15 minutes of my time.
To this end, the amount of time taken from creating the prototype application and finalising the settings within the app was quite short so I think it was definitely worth it to take this approach.
Interaction With Designers
I had good feedback from the design department. Designers work visually and want to tweak settings and values on-the-fly. Giving them a visual interface to perfect this feature is more in tune with how those departments work so I think they found this approach more natural and efficient. It also allowed them to use their creativity to the fullest as there was no engineering bottleneck in the way.
Thanks for Reading!
Have you used tooling like this before? Was it helpful and how did it help you integrate with your design and product teams?
I believe that engineers shouldn't just code. They should also engage in the product development lifecycle. I think that understanding what product teams want and helping them realise their visions makes us better engineers and helps us grow as contributors across the entirety of a project, not just its codebase.
To that end, custom tooling like this can help bring us closer to the product team and helps them realise their visions more easily, often resulting in better, more cohesive products.
Thanks again for checking this post out. I hope it helps you and your team make better products going forward...
Costco が扱っているデータのほとんどは Cost Explorer API から取得したデータそのものや、それらを加工したものです。API のコールには 1 リクエストあたり 0.01USD と、積み重なるとそれなりに高額になりうる料金がかかるため、バッチ処理で定期的に Costco に取り込むようにしています。
予算と月次のふりかえりに関する機能
予算を Cost Explorer のフィルタとして定義する
Costco には予算という概念があります。これは組織としての予算に対して Cost Explorer のフィルタを紐付けるものです。ここで設定した Cost Explorer のフィルタは「ある予算が何を意味しているのか」をコード (JSON) として直接説明しています。ここに日本語のような曖昧さは発生しません。さらに良いことに、このフィルタは実際に動きます。フィルタを使って Cost Explorer で簡単にコストを可視化できるのです。
クックパッドでは、従来 EC2 について RI を購入していましたが、 RI の維持管理を楽にするために既存の RI が切れ次第、Savings Plans (Compute) に置き換えを進めています。Savings Plans (Compute) では、一定のルールにしたがってリザーブが自動的に適用されるため、結果的にどのリージョンにどの程度 Savings Plans が適用されたかは Cost Explorer API から取得したデータを使って自前で計算する必要があります。
クックパッドの DWH チームの尽力により CUR が Redshift Spectrum で簡単にクエリできるように整備されており、社内の Tableau を利用することで CUR のデータをベースにしたダッシュボードを作れるようになっています。ただし、CUR のデータは良くも悪くも「生」なデータで、非常に多くのカラムがあり、それらを正しく組み合わせてダッシュボードを作ることは、まさに Tableau 職人の技といえるでしょう。
わたしは残念ながらその域には達していないことと、Route 53 のドメイン請求一覧の機能などは Tableau では実現できないため、Costco のようなウェブアプリケーションの形にしました。その他にも、CUR だけでは Cost Explorer API で取得できるようなコストの予測値は得られませんし、Cost Explorer API では簡単に得られる償却コストの計算も難しいです。
ただし、今後 Cost Explorer API では得られないような情報を Costco で扱いたくなった場合には、CUR のデータをもとに Redshift で集計して Costco に取り込む、というニーズが発生するかもしれません。また、Costco 上でグラフィカルに表示することが難しい場合に Tableau ダッシュボードにリンクするなど、うまく活用していく道があるかどうかは常に考えています。
ともすれば、Costco のようなアプリケーションを開発することは、組織の規模感や状況によってはオーバーエンジニアリングとなるかもしれません。しかしながら、その根底にある考え方はあらゆる組織で役立つものだと信じています。たとえば、コスト配分タグの管理を Google スプレッドシートなどのツールで小さく始めてみるのも良いかもしれません。