Furyu
[フリュー公式]

Tech Blog

フリュー株式会社の技術ブログです

2015年11月25日

morioka

watchbuildでiTunes Connect処理中を快適に過ごす

こんにちは。 コンテンツメディア事業部で主にピクトリンクアプリを開発している盛岡です。

初めての連続ブログ投稿です。

突然ですが最近の悩み事として、iTunes Connectが利用者にやさしくないってことがありました。今回は、それがうまく解決したので紹介します。

やさしくない?

iOSアプリを公開する場合には、ざっくりと以下のような手順を踏むことになります。

  1. iTunes Connectにて新規リリースバージョンの登録
  2. iOSアプリを実装・ビルド
  3. ビルドしたiOSアプリのアーカイブをiTunes Connectへアップロード
  4. iTunes Connectからレビュー対象ビルドを選択しレビュー申請

この中のステップ3〜4の間で、iTunes Connect側で対象ビルドを選択できず「処理中」というステータスになることがあります。

以前は10分程度で完了していたのですが、最近だと平均2時間… ひどい時だと半日待ちという状況があります。

またTIPSとしてiTuens Connectを表示しているブラウザを変えてみるとか、再度ビルドアーカイブをアップしたら行けた!みたいな報告があったり、iOSアプリ開発における”闇”な感じが漂っているこのごろです。

fastlaneとwatchbuild

世界中みんな困っているらしく、以前にも少し触れたfastlaneというプロジェクトにて”iTunes Connect処理中待ち確認ツール”そのものずばりが公開されているようです。それが「watchbuild」です。

  • fastlane

https://github.com/fastlane

fastlaneについてもう少し説明しておくと、「Continuous Delivery for iOS Apps」を達成するための、iOSアプリのリリースにまつわる工数削減やコマンドラインツール化を提供するプロジェクトです。 最近Twitter Fabricに組み込まれましたね。

その中でwatchbuildはコマンドラインツールとして提供されており、上記の処理待ち状態の確認作業を代行してくれます。

早速使ってみる

以下のgithubプロジェクトでソースコードとインストール方法など提供されています。

https://github.com/fastlane/watchbuild

基本的には上記URLどおりにインストールするだけです。 Ruby gemsがインストールされていればうまく行くはずです。

早速実行した結果を見てみましょう。

iOSアプリのidentifierとiTunes Connectのログインアカウントを指定して実行します。初回実行時にiTunes Connectのログインパスワードが聞かれます。

上記実行結果を見てもらうと分かると思いますが、数十秒おきにループしてくれてますね。処理中が完了すると、”Successfully finished processign the build”と出力されて完了する感じです。

今回は117分間もがんばってもらってました。偉い!

まとめ

エンジニアにとって改善活動を行うことは重要ですが、思わぬところで時間を取られている場合の対応については見逃しがちでした。

今回は世界中の誰しもが困っていることだったので、解決してくれる人が居たので助かりました。今後については、似たような待ち作業が発生した時にただ待つだけではなく、自分でソフトウェアを書いて解決した方が良さそうなパターンもあるのだなと勉強になりました。

みなさんも良いエンジニアライフをお過ごしください。


2015年11月18日

morioka

関西モバイルアプリ研究会 #7を開催しました!

みなさん、こんにちは。ピクトリンクアプリを開発している盛岡です。

久方ぶりのブログ更新です。jyukutyoのサンフランシスコレポートの間に割り込んでみました。

今回のエントリは、先日フリューにて関西モバイルアプリ研究会#7を開催したので紹介したく書いてます。

関西モバイルアプリ研究会とは?

enter image description here

http://kanmoba.connpass.com/


関西モバイルアプリ研究会名のとおり、関西在住のエンジニアによるiOS/Androidアプリ開発者向けの勉強会です。

毎回コアなネタが繰り出される、おもしろい勉強会になっています。発表内容については上記URLの資料から参照出来ます。また、Twitterのハッシュタグ ‘#関モバ’ で検索してもらうと、雰囲気などがある程度伝わるのかなと思います。

毎月1回ペースで実施されており、今回は7回目でした。第8回目も予定されてます。

6回目までは株式会社はてなさんで実施していたのですが、7回目はフリューで開催することとなりました。

#7のトピックス

勉強会の進め方・発表形式は1人5分間のライトニングトークを、多めの人数(10人前後)で回していくというものです。

これが5分なのに深い内容が多い。第7回目は以下のような発表内容でした

  • Android6のセキュリティフレームワーク
  • iOSのA/Bテスト
  • Windows(Phone)のプッシュ通知処理
  • Retrofit2
  • instagram APIを利用したiOSアプリ開発
  • Google Cardboard
  • iOSのbitcodeについて
  • Fastlane
  • アプリの権利を委譲する

そうそうたる発表内容ですね。最新のiOS情報に関わるものからWindowsまで!

気になった発表

アプリの権利を委譲する話は興味深く聞かせてもらいました。

企業でアプリを作成していると、たまに話題になることがあります。が、仕様は頻繁に変わるみたいです。 発表者の方も「2015年10月時点での情報なので注意してください」と頻繁にアナウンスされてました。

また弊社でもFastlaneの導入を検討しており、実際の利用動向などチェックしていきたいなと感じました。

ちなみにFastlaneとは「Continuous Delivery for iOS Apps」を達成するためのプロジェクトになってます。

https://github.com/fastlane/fastlane

フリューで開催してみて

関西の凄腕エンジニアの方々との交流に一役かえるというのは、中々ない機会だと思います。実際に開催してみて凄く楽しかったですし貴重な体験でした。 発表内容を見てもらえればわかると思いますが、このような内容が聞ける会はそれほどないので是非継続していきたいですね。

事前準備等で不慣れな点がありご迷惑をおかけしたかと思いまが、京都タワー地下という立地条件は良かったという意見もあり、希望があれば会場提供も継続させてもらえればと思います。

今後も関西のモバイル開発を盛り上げていきましょう!


2015年11月16日

sakata

JavaOne 2015 サンフランシスコに参加しました!(2日目パート2)

Hello World! コンテンツ・メディア第1事業部の、jyukutyoこと阪田です。JavaOneは一番最初のセッションが始まるのは8:30、最後のセッションが終わるのは21:45です。お昼休みはありませんのでセッション間で昼食を済ませつつ、ずっとセッションを聴き続けるため、期間中はかなりハードです。観光などする時間はなく、お土産を買う時間を捻出するのもかなり大変でした。

Introduction to Modular Development

キーノートでもあった「Project Jigsaw」の紹介セッションです。構文はキーノートのレポートを参照してください。 今後java.lang.Objectなどはプラットフォームが提供するjava.baseモジュールにまとめられ、暗黙的に依存することとなります。モジュールのアクセシビリティは、モジュール内の公開されたパッケージのpublicなものだけです。公開されていないパッケージのpublicにはアクセスできないため、publicであるだけではアクセシビリティはありません。 モジュールはmodule-info.javaに記述し、コンパイルに含める必要があります。他のモジュールを使うときはjava -modulepath dir1:dir2のようにします。モジュールのmain()メソッドを実行するときはjava -m モジュール名/モジュールの完全修飾名で実行します。このあたりのことはProject Jigsawのクイックスタートページがわかりやすいです。-Xdiag:resolverオプションをつけると、依存関係の解決をログに出力することができるようです。

invokedynamic for Mere Mortals

JVM命令の1つであるinvokedynamic(indy)についてです。 JVMはもちろんJavaのために設計されたものですが、近年複数のプログラミング言語がJVM上で動作するようになりました。いまやどんな種類のプログラミング言語にとってもすばらしいプラットフォームとなっています。 Java以外の言語にとっての要求は、例えばcontinuationsやdyanmic invocation、tail recursion、interface injectionなどです。dyanmic invocation(動的呼び出し)をするために動的型付けがあるわけですが、動的型付けでは、呼び出しを実行するその瞬間までその型がいったい何なのか知ることができません。動的型付けは型妨害ではないし、弱い型付けでもありません。動的型付け言語は完全な型情報がなく、より実行時のチェックが求められます。indyができるまではこういった言語をJVMで動作させるためにはリフレクションを使うしかありませんでした。ただし、リフレクションにすると動作が遅く、引数がすべてObjectであったりとさまざまな問題がありました。リフレクションではインライン化できず最適化できませんでした。


JSR-292でjava.lang.invokeのAPIが追加されましたが、これはよりよいリフレクションと言えるかもしれません。そしてinvokedynamic命令が追加されました。これはリンケージのためにディスパッチするものです。indyはJVM命令セットができてから初めて追加された命令で、そして初めてJava以外の言語をターゲットにした命令です。メソッドハンドルとコールサイト、そしてブートストラップメソッド(bsm)という概念があります。メソッドハンドルはメソッドを指し示すものです。関数ポインタ的な考えでよいと思います。メソッドハンドルのパフォーマンスですが、リフレクションよりはかなり早くなります。indyとは独立して使うことができます。コールサイトがメソッドハンドルを使ってメソッド呼び出しをします。動的という意味では、コールサイトは変わらずメソッドハンドルを変えることで呼び出すメソッドを換えれられます。つまり、コールサイトがメソッドハンドルを保持しています。


次にブートストラップのステップです。indyを使ったコードを実行するとき、ブートストラップメソッド(bsm)を呼び出します。bsmはコールサイトを返すメソッドであるため、コールサイトを通じてメソッドハンドルへ、メソッドハンドルからメソッドを呼び出すというステップです。2回目以降の実行は、bsmは呼び出さずにコールサイトを通じて呼び出すだけです。リンケージは呼び出しではなく、リンケージは一度だけ実行する必要があるもので、またコストの高い処理でもあります。一方呼び出しは何度も実行するもので、jmp/callを必要とします。indyによってリンケージが変えました。java.lang.invokeのAPIはindyなしでもよく使われます。JVMはどの言語にとってもすばらしいプラットフォームと言えるでしょう。

Compact Strings: A Memory-Efficient Internal Representation for Strings

JEP(JDK Enhancement Proposals) 254: Compact Stringsについてです。Stringの内部表現でもっと効果的にリソースを使うようにしようというものです。個人的にはこれが2日目で一番興味深かったセッションですね。JDK9でのリリースが予定されています。 JavaはUTF-16をサポートしており、2バイト文字を使います。より効果的にリソースを使うようにしつつも、完全な後方互換性を保つようにします。どんな使用状況でも以前のスループットパフォーマンスは維持します。JDK6で失敗したCompressed Stringsの置き換えです。さまざまなアプリケーションから統計をとったところ、Stringの大部分は小さいもので、75%以上は35文字未満でした。また、x64でcompressd referenceを使わないと2倍メモリを使うことになります。


新しいStringクラスのデザインは次のようになります。後方互換性を維持しつつも、内部表現は変更します。UTF-16だけで表現するのではなく、 UTF-16またはISO-8859-1/Latin-1を使うようにします。1バイト文字はISO-8859-1/Latin-1で、2バイト文字はUTF-16とし、char配列ではなくbyte配列で表現するようにします。さらにencodingというbyteのフィールドを追加し、何のエンコーディングか示唆するようにします。なぜUTF-8ではないのかというと、UTF-8は文字幅が可変なためです。StringのAPIは文字シーケンスにランダムアクセスするものがたくさんあります。Stringクラスはこう変わるイメージです。JDK8ではStringクラスはこうでした。

JEP 254ではこうなります。

さきほどJDK6での失敗と言いましたが、具体的に見てみます。JDK6のCompressed Stringsがないときはこうでした。

Compressed Stringsでこうなりました。

valueがObjectであり、byte[]かchar[]かを判断する必要がありました。そのためCompressed StringsではStringクラスの2つの実装があることとなります。メンテナンスのコストもかかります。JREでのサポートに限界もありました。JEP 254ではbyte[]のみとなります。encodingフィールドも追加します。JREでcompressed stringsへのサポートも拡張できるでしょう。


JMH(Javaのマイクロベンチマークツール)でのベンチマークでは、すべてのケースで処理が早くなっています。メモリ使用量は21%削減できました。スループットも5%増加してよくなっています。

jyukutyoコメント

2日目に出たセッションからいくつかをピックアップしてレポートしました。これでまだ2日目!あと3日分あります。長いレポートになりますが、ぜひ最後までお付き合いください。


2015年11月12日

sakata

JavaOne 2015 サンフランシスコに参加しました!(2日目パート1)

Hello World! コンテンツ・メディア第1事業部の、jyukutyoこと阪田です。 2日目からいよいよ本格的なセッションが始まります。すべてのセッションについては書けないので、いくつかを抜粋して書いていきます。私の興味はJVMにあり、Javaの新しい言語仕様よりもGCやパフォーマンスチューニングのセッションに多く出ました。

GC Tuning Confessions of a Performance Engineer

パフォーマンスエンジニアによるGCのチューニングについてのお話です。やはり日本で英語スピーカーが話すときとまったく話すスピードが違います。すべてを理解しようとせず、ヒアリングと資料の内容を照らし合わせながら必死に理解を進めました。

GCにおけるメトリクスには、たとえば次のようなものがあります。

  • GCのイベント数
  • 最小/最大実行時間
  • 平均実行時間
  • 99%平均実行時間

GCの内部に迫っていくと、GCがあるからといってメモリリークがなくなるわけでないということです。そしてGCにはトレードオフがあります。今のアプリケーションはどんどんヒープ領域が大きくなっていますが、それゆえにフルGCは怖いものとなっています。GCのチューニングの観点からは、登場人物が2人います。スループットとレイテンシです。GCには世代別や並列などの種類がありますが、OpenJDKではすべてのGCは世代別GCです。 アプリケーションがレイテンシを重視しているか、GCを並列にするかどうか、さらにGCでコンパクションするかどうかでCMS(Concurrent Mark-Sweep)かG1GCにするかを選択します。

GCアルゴリズム

ここからはGCアルゴリズムの復習です。まずヒープ領域はEden、Survivor0、Survivor1を合わせたYoung領域と、残りのOld領域に分けられます。Young領域とOld領域では、GCのアルゴリズムを別々にできます。 シリアルコレクタであれば、YoungもOldも両方シングルスレッドでGCします。スループットコレクタ(パラレルコレクタ)はYoungもOldもマルチスレッドでGCし、コンパクションもします。CMSはYoungはことごとくGCし、Oldはmostly concurrent(”ほぼ”並列)にGCします。 プロモーション(昇格)とはYoungからOldへの昇格を指します。CMSはOldへのプロモーションが早くなります。またCMSではフリーリストを使って領域を管理しています。もし割り当てられる領域がなかったら、GCはfailureとなります。コンカレントのサイクルが終わる前にOldがいっぱいになることがあり、そのときはスペースを空けます。CMSはフラグメンテーションが発生します。

G1GC

G1はリージョナルヒープです。リージョンごとに世代があります。GC時に特定のリージョンにオブジェクトを集めます。クリーンアップフェーズでリージョンが空になれば、別の世代のリージョン(同じでもよいが)として再利用します。G1にはYoungもOldもすべてGCするmixed collectionがあります。もしすべてのリージョンがいっぱいになってしまえば、evacuation failureとなります。evacuation failureになってしまうととても高コストな処理となり、すぐにフルGCが走ります。 GCのチューニングについてのアドバイスは「あまりチューンしない」ということです。サイズと希望停止時間(pause time goal)ぐらいを指定するだけでよいです。あとは、初期ヒープ占有の閾値が問題を起こすかもしれません。マーキングサイクルが長い場合に並列マークスレッドを増やすくらいでよいでしょう。YoungのTo領域がevacuation failureを引き起こしている場合は、-XX:G1ReservePercentの値を増やす方がいいです。 G1にもフラグメンテーションがあります。デフォルトでは5%ほどです。さらに巨大オブジェクトの問題もあります。巨大なオブジェクトをヒープに割り当てるとき、そのサイズがリージョンの50%未満なら単純に割り当てるだけです。50%以上でも割り当てられますが、もしサイズがリージョンより大きい場合はどうなるでしょうか?隣接した複数のリージョンを使います。そうすると、フラグメンテーションは発生してしまいます。ただし、巨大オブジェクトは数は少なく生存期間が短いことが多いので、問題にならないでしょう。もし数が多く生存期間が長ければ、evacuation failureを引き起こすかもしれません。Oldの占有率を増やしているでしょうから。 G1のGCログを見たとき、remarkポーズ時間が長く、Ref Procがあるならオプションをつけた方がよいでしょう(何のオプションか不明)。

セッションのまとめ

デフォルトのGCであれば、TenuringThresholdで世代サイズを設定しましょう。-XX:+UseAdaptiveSizePolicyも必要です。スループットにはYoung領域のサイズが重要です。 CMSであれば、Fractionと-XX:+UseCMSInitiatingOccupancyOnlyがマーキングの閾値を設定する助けになります。閾値はOld領域の占有率のパーセンテージで表現されます。CMSではプロモーションが早く、それがフラグメンテーションを発生させる原因ともなっています。 G1は、最大希望停止時間(max pause time goal)が重要です。あとはデフォルト値をしっかり知ることが大切です。G1はヒープ領域を2048のリージョンにわけ、各リージョンのサイズは1MBから32MBの間になります。アグレッシブな停止時間は設定しないこと!オーバーヘッドが増えるだけです。 最後はJavaパフォーマンス(http://www.amazon.co.jp/dp/4873117186/)読もうね!で終わりました。

jyukutyoコメント

JDK9ではG1がデフォルトになる予定のようです。ただ、CMSとG1のどちらを使うかという判断基準が私にはまだわかっていません。OpenJDKでのトラブルシューティングをされている方に話をうかがったところ、ヒープが8GBを超えるようならG1、それ以下であればリージョンが小さくなるためCMSでよい、と教えていただきました。ただし、CMSでフラグメンテーションが問題となるようなときは8GB未満でもG1でよいかもしれません。
ヒープが8GB未満であればG1を選択するメリットがないので、CMSでよい。8GB以上でレスポンスタイムを一定以下に抑えたいならG1、全体的なスループットを上げたいならCMSだがフラグメンテーションが起きるならG1にする。8GB以下でフラグメンテーションが起きるなら Parallelを選ぶのが基本戦略と改めて教えていただきました!ありがとうございます!


2015年11月10日

sakata

JavaOne 2015 サンフランシスコに参加しました!(1日目)

Hello World! コンテンツ・メディア第1事業部の、jyukutyoこと阪田です。

JavaOneとは

みなさんはJavaOneというイベント、カンファレンスをご存知でしょうか? JavaOneは、オラクル社(以前はサン・マイクロシステムズ)が1996年から毎年開催している、Javaに関する最大級のカンファレンスです。サンフランシスコで5日間、400以上のセッションがあります。朝から晩までJavaに浸っていられる、夢のような内容となっています。

私は今回海外出張としてJavaOneに”初”参加しました。このブログでその様子をレポートします。 まずこのエントリでは、サンフランシスコ国際空港に到着してから、1日目を終えるまでをレポートします。

移動について

日本からサンフランシスコは、関西国際空港からだと行きは飛行機で9時間で到着します。時差は16時間あるため、日本を夕方に出発しても、サンフランシスコに到着するとその日の午前中に逆戻りします。

CIMG1729

9時間のフライトとはいえ、離着陸や食事の時間があるため、それほど長時間眠ることはできず、到着すると疲労と睡魔を感じます。空港からJavaOneの会場となるユニオンスクエア近辺までは、電車に1本乗るだけで行けます。

CIMG1730

BARTと呼ばれるものです。「Powell St. Station」が直近の駅で、片道8ドルほどかかります。BARTのチケットを購入するのは少し難しいので、初めての方はサンフランシスコの高速鉄道BART(バート) [サンフランシスコ] All About などを参考に、事前に予習しておいた方がよいでしょう。ちなみに、私は予習していても少し詰まりました。

到着日はJavaOne開催日の前日でしたが、前日からRegistration(登録)できます。モスコーン・センターまたはヒルトン・サンフランシスコ・ユニオンスクエアで登録できます。私はヒルトンで登録しました。

CIMG1755

事前にメールで送られてくるQRコードを読み取り、パスとノベルティとして定番のJavaOneリュック、Duke Tシャツなどに加えて、水筒がもらえました。

CSH5pRWUwAAtmf9.jpg-largeCSH7yRKUcAAxWpM.jpg-large

キーノートレポート!

1日目はキーノート(基調講演)とユーザグループのセッションが主にあります。この日だけ、モスコーン・センターでの開催となります。 モスコーンはまさにお祭りのよう!長い通りがすべてカンファレンス施設で埋められています。実は、JavaOneと同時開催でOracle OpenWorld(OOW)というイベントも開催されており、モスコーンはOOWの方が主に使用するため、オラクル社の赤で統一されています。

CIMG1739

キーノートの会場は日本では考えられないくらい広く、軽く数千人は入る規模です。

CIMG1744

キーノートでの技術的な話題としては、「Project Jigsaw」と「Project Valhalla」、「Project Panama」です。と言っても、もう数年間ずっとこれしか出ていないわけですが、とくに劇的な進捗があるようにも見えませんでした。 Project Jigsawは、Javaのモジュール化のためのものです。新たなキーワードとして”module”を導入し、モジュールの依存関係と公開するパッケージを指定できます。たとえば、CommonsのライブラリBeanUtilsだと、以下のような感じになります。

BeanUtilsはcommons.loggingに依存していて、org.apache.commons.beanutilsパッケージを外部に公開していることになります。公開していないパッケージは、たとえpubclicなクラスが含まれていてもアクセスできないようになります。moduleはパッケージよりも上位の概念となります。こうして、JARが利用する外部パッケージと、JARが外部に公開するパッケージをそれぞれ決められるようになります。 Project ValhallaではValue Typesという新しい型が導入されます。以下のようなクラスがあるとします。

その配列”Point[]”を扱うとき、各要素は参照を経由していました。この場合、データへのアクセスにオーバーヘッドがあります。データをまとめて扱うようにしてCPUのキャッシュにおけば、キャッシュミスが減りパフォーマンスが向上します。そのようなときのために新たなキーワード”value”が導入されます。

こうすることで、Value Typeとして扱われるようになります。イミュータブルに限定されることに注意してください。 もう1つ、Project Valhallaでは”Specialized Generics”があります。ご存知の通り、Javaのジェネリクスではプリミティブ型は指定できず、代わりにラッパークラスを指定していました。

Specialized Genericsでプリミティブ型を直接指定できるようになります。

IntStreamなんていらなかったんや…そしてProject Panamaはあまり詳しい話はなかったように思います。 このあと、サン・マイクロソフト創業者のスコット・マクニーリがビデオで登場し、「Javaプログラマにとって最悪な12のこと」を読み上げ、盛り上がりは最高潮を迎えました。

ユーザグループセッションレポート!

ユーザグループのセッションでは、ウクライナのJUG(Java User Group)である「JUG.ua」の取り組みが非常に興味深かったです。 JUG.uaではAdopt a JSR(Java Specification Requests:Java仕様リクエスト)の活動として、どのJSRをサポートするかグループ内で話し合い、JSON-B仕様をサポートすることに決めました。そこから仕様のメーリングリストに入り、実装のサンドボックスをGitHubに作り、公開された質問や提案をグループ内で共有しました。それからグループからの質問やコメント、提案を出していきました。結果として60以上の提案やコメントを出し、そのうち30は組み込まれたそうです。 私も関西Javaエンジニアの会(KansaiJUG)というJUGを運営し、昨年JCPメンバーとなっています。今後のAdopt a JSRへの参画に、よいヒントをもらえたと考えています。

Java Lounge @ Oracle Welcome Reception

1日目の夜はウェルカムレセプションがあり、楽しい雰囲気で終わりました。

CIMG1748

1日目までのレポートは以上です。2日目以降のレポートもお楽しみに!