Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Real World
Android Akka
Taisuke Oe
自己紹介?
麻植泰輔 / TaisukeOe
GitHub: / Twitter:
お仕事
セプテーニ・オリジナル 技術アドバイザーとしてPullReqレビュー/新卒研修
座長
taisukeoe @OE_uia
BONX Android Ap...
次回のScalaMatsuri
2018年3月予定!
現在日程調整中。お楽しみに!
今日話すこと
VoIPクライアント
VoIP : Voice Over Internet Protocol
VoIPサンプル
taisukeoe/VoIPAkka
Real World Example
BONXとは?
アウトドア用の通話システム
スノーボード
スキー
釣り
サイクリング
...
BONXアーキテクチャ
アプリ
VoIPクライアント
Android : Scala
iOS : Objective C / Swift
サーバー
APIサーバー : Ruby on Rails
Voiceサーバー : golang
Bluet...
Android Akkaを使ったワケ
VoIPはステートフルな非同期ストリーム処理
Upstream
Recorder -> some DSP -> Encoder -> Socket
Downstream
Socket -> Decoder -> some DSP -> Player
DSP : Digital Signal...
求められる障害からの回復力(Resiliency).
アウトドアでは、様々なエラーに遭遇する
不安定なネットワーク
圏外<->圏内間の度重なる移動
ハードウェアI/Oエラー
Bluetooth切断
アウトドアで遊んでいる最中は画面操作できないの...
更に悪いことに:
エラーは必ずしも問題のコンポーネントで捕捉されない。
下流で気づくことがある
すなわちエラーを逆方向に伝搬させたい
問題のあるコンポーネントは、壊れた音声データを生むかもしれない
そしてノイズの原因になりうる
すなわちエラーの...
まとめ: BONXの要求仕様
ステートフルな非同期ストリーム処理
障害からの回復力
そこでAkkaの出番!
Akkaは 並行プログラミング、障害からの自動回復
... そして分散システムを構築するためのtoolkit.
(ステートフルな) 並行プログラミングのために
メッセージ駆動なアクターモデル
アクターは、状態を内部に閉じ込めたまま、並行プログラミングが容易
状態を内部に閉じ込めたActorの例
class PlayActor() extends Actor {
private val track: AudioTrack = createNewAudioTrack //state. Thread U...
Akkaによる障害からの回復力(Resiliency)
例外のハンドリング
Actorヒエラルキー
子アクターをsupervisorStrategyにもとづいてRestart, Stop, Resume
これによるRestartは メッセージボ...
アクターによる例外のハンドリングのサンプル
class ExceptionHandlingActor() extends Actor{
private var childActor:ActorRef = createChildActor
ove...
Recaps: なぜAkkaがうまく働いたのか
ステートフルな並行プログラミング
アクターの状態のカプセル化 / 一度に一つだけメッセージを処理するのでロック不要
障害からの回復力
アクターのヒエラルキーないしはモニタリングで管理
Akkaによ...
なぜ「だいたい」なのか ?
ものによっては例外として検知しにくい問題がある
オーディオドライバが場合によっては(ブロックしたまま)沈黙し、何も返さないことがある
銀の弾丸はない
Askパターンで、Ack が Timeout 内に返ってくるかチェ...
どうしてScalaがAndroidで使えるのか?
ビルドツールチェイン
scalac がScalaのソースをJava bytecodeにコンパイル
Android SDK の dex が Java bytecode を Dalvik Executable bytecodes に翻訳
Andro...
Android端末のスペックも上がってきた
ここ数年の agship級端末だと、最低でも:
4 to 10 cores CPU
3 to 4 GB memories
largeHeap=true で512MB程度使える
Q. じゃあScala Android使うべき?
万人にオススメはしない 
技術にはトレードオフがつきもの
Pros & Cons
Pros
豊富な言語機能とエコシステム ecosystem.
並行プログラミング
コレクションAPI
代数的データ型とパターンマッチ
トレイト
生産的
0.5 ~ 1.2 人で2年間新機能開発と運用まわしてました
サーバーサイドもScalaだと...
他にScalaで嬉しい話
(View以外の)ステートレスな並行プログラミング
Viewの修正はUIThreadで行うため、Viewについては排他制御を考える必要性が薄い
Scalaの並行プログラミングAPIは優秀
Scala標準のFuture悪くないですよ.
UIThreadで実行するためのExecutionContextを定義して onComplete, andThen 等に明
示的に渡せる
UIExecutionContext Pattern
class UIExecutionContext(activity:Activity, reporter: Throwable => Unit)
extends ExecutionConte...
その他のScala Androidプロジェクトたち
セプテーニ・オリジナル
hits 6 million DLs!
47 Degrees
Akkaモジュール有り.
GANMA!
47deg/macroid
47deg/nine-cards-v2...
Cons
dexファイルあたり、メソッド数 64k の上限.
Scala標準ライブラリのjarはちょっと大きすぎる.
ProguardかMultiDexが必要.
Java8 supportなし
Android SDK toolchain はいま...
Proguard
Proguardは使用されていないクラス、フィールド、メソッドを除くポストプロセシングツー
ル.
使用されていない とは 参照されていない.
Proguard はリフレクションを解しない.
AkkaはリフレクションをProps...
とはいえ、Proguardの設定って最初から全部自分でやらなき
ゃいけないのか?
そんなことはない
Scala標準のライブラリ用のProguard設定は組み込み済
akka.actor と akka.io パッケージについては作りました
sca...
新しいライブラリについて
Proguardの設定を簡単にやる方法(手抜き編)
実際とりあえず試すにはこれで十分
ライブラリが十分小さい限りにおいては.
例えば、Akkaについて同じ方法で設定するなら、proguard-con g.txtに以下の一行を足
す:
-keep class akka.** { *; }
後でちゃ...
Proguardの設定方法(推奨)
リフレクションで参照されているクラスを調べよう
grep -r "classOf" . が最も簡単
FQCN(フル修飾名)が.confファイルなどの設定ファイルに記述されているクラスを調べよ
う.
ラインタイ...
Proguard-Con gは最終的にこんな感じ:
# Akka configuration
# Akka 2.3.16
## for akka.actor
### Classes used in reference.conf
#### akk...
Proguardの設定でapkファイルのAPIメソッド数の比較
In akka.actor and akka.io 2.3.16 (and Scala 2.11.11)
Proguard setting # of methods in
dex
...
AndroidはJava8をサポートするのか?
GoogleはAndroidのdex toolchainがJava8をサポートする旨アナウンスしている.
Java 8 Language Features Support Update - And...
もしAndroidがJava8サポートしたら
Scala 2.12以上
Scala標準ライブラリjarが小さく。
Dotty(Scala 3.0)が 由来のcallgraph analysisによって、dead codeをなく
せるかも. (P...
メモリ管理
Android GCはConcurrent Mark & Sweep.
WrappedArray#mapやその他の高階関数はprimitive型をboxingすることがある
特にコピーが走りやすい場所ではring bu erが良い
...
結論
ActorモデルはAndroidでもうまく働く。特に ステートフル な並行プログラミングにおいて。
Akkaの障害からの復旧力は(アウトドアのような)エラーの起きやすい環境では役立つ
BONX AndroidアプリはAkkaの特長を活用し...
Real World Android Akka - 日本語版
Real World Android Akka - 日本語版
Real World Android Akka - 日本語版
Upcoming SlideShare
Loading in …5
×

Real World Android Akka - 日本語版

3,144 views

Published on

Real World Android Akka

Published in: Software
  • Be the first to comment

  • Be the first to like this

Real World Android Akka - 日本語版

  1. 1. Real World Android Akka Taisuke Oe
  2. 2. 自己紹介? 麻植泰輔 / TaisukeOe GitHub: / Twitter: お仕事 セプテーニ・オリジナル 技術アドバイザーとしてPullReqレビュー/新卒研修 座長 taisukeoe @OE_uia BONX Android App ScalaMatsuri
  3. 3. 次回のScalaMatsuri 2018年3月予定! 現在日程調整中。お楽しみに!
  4. 4. 今日話すこと VoIPクライアント VoIP : Voice Over Internet Protocol
  5. 5. VoIPサンプル taisukeoe/VoIPAkka
  6. 6. Real World Example
  7. 7. BONXとは? アウトドア用の通話システム スノーボード スキー 釣り サイクリング ...
  8. 8. BONXアーキテクチャ アプリ VoIPクライアント Android : Scala iOS : Objective C / Swift サーバー APIサーバー : Ruby on Rails Voiceサーバー : golang Bluetoothヘッドセット
  9. 9. Android Akkaを使ったワケ
  10. 10. VoIPはステートフルな非同期ストリーム処理
  11. 11. Upstream Recorder -> some DSP -> Encoder -> Socket Downstream Socket -> Decoder -> some DSP -> Player DSP : Digital Signal Processing 全てのコンポーネントは状態が有り、更に スレッドセーフではない.
  12. 12. 求められる障害からの回復力(Resiliency). アウトドアでは、様々なエラーに遭遇する 不安定なネットワーク 圏外<->圏内間の度重なる移動 ハードウェアI/Oエラー Bluetooth切断 アウトドアで遊んでいる最中は画面操作できないので、自動復旧が肝。
  13. 13. 更に悪いことに: エラーは必ずしも問題のコンポーネントで捕捉されない。 下流で気づくことがある すなわちエラーを逆方向に伝搬させたい 問題のあるコンポーネントは、壊れた音声データを生むかもしれない そしてノイズの原因になりうる すなわちエラーの種類によっては、キューにたまった音声データを消さなければいけない (逆もまた然り)
  14. 14. まとめ: BONXの要求仕様 ステートフルな非同期ストリーム処理 障害からの回復力
  15. 15. そこでAkkaの出番! Akkaは 並行プログラミング、障害からの自動回復 ... そして分散システムを構築するためのtoolkit.
  16. 16. (ステートフルな) 並行プログラミングのために メッセージ駆動なアクターモデル アクターは、状態を内部に閉じ込めたまま、並行プログラミングが容易
  17. 17. 状態を内部に閉じ込めたActorの例 class PlayActor() extends Actor { private val track: AudioTrack = createNewAudioTrack //state. Thread UN-safe override def preStart(): Unit = track.play() override def receive: Receive = { //An actor retrieves and process a message from its mailbox one-at-a-time. case AudioPacketMessage(content:ByteString) => track.write(content.toArray[Byte], 0, content.length) } override def postStop(): Unit = { track.stop() track.flush() track.release() } }
  18. 18. Akkaによる障害からの回復力(Resiliency) 例外のハンドリング Actorヒエラルキー 子アクターをsupervisorStrategyにもとづいてRestart, Stop, Resume これによるRestartは メッセージボックスにメッセージを貯める. モニタリング (Death watch) 監視対象のアクターがstopすると、監視側のアクターはTerminated(actorRef) メッセー ジを受け取るので、そこで再生成する これによるアクター再生性は メッセージボックス内のメッセージを破棄する.
  19. 19. アクターによる例外のハンドリングのサンプル class ExceptionHandlingActor() extends Actor{ private var childActor:ActorRef = createChildActor override def supervisorStrategy: SupervisorStrategy = OneForOneStrategy(){ //Want to reset all mailboxes case _:BrokenAudioDataException => Stop //At default, child actors will be restarted with keeping their mailbox. case t => super.supervisorStrategy.decider.applyOrElse(t, (_:Any) => Escalate) } def receive = { //Stopped childActor will be recreated. case Terminated(ref) => if(childActor == ref) { context.unwatch(childActor) childActor = createChildActor } } private def createChildActor = { val c = context.child(ChildActor.props) context watch c c } }
  20. 20. Recaps: なぜAkkaがうまく働いたのか ステートフルな並行プログラミング アクターの状態のカプセル化 / 一度に一つだけメッセージを処理するのでロック不要 障害からの回復力 アクターのヒエラルキーないしはモニタリングで管理 AkkaによってVoIP問題が「だいたい」解消した!
  21. 21. なぜ「だいたい」なのか ? ものによっては例外として検知しにくい問題がある オーディオドライバが場合によっては(ブロックしたまま)沈黙し、何も返さないことがある 銀の弾丸はない Askパターンで、Ack が Timeout 内に返ってくるかチェック。 もし Ask がタイムアウトしたら、stopし再生成。 とはいえ、まずは「例外」として問題を検知する方法を探るべき あまりオススメはしない
  22. 22. どうしてScalaがAndroidで使えるのか?
  23. 23. ビルドツールチェイン scalac がScalaのソースをJava bytecodeにコンパイル Android SDK の dex が Java bytecode を Dalvik Executable bytecodes に翻訳 Android標準のビルドシステムの主要機能は抑えている sbt pluginと組み合わせ等が柔軟 scala-android/sbt-android
  24. 24. Android端末のスペックも上がってきた ここ数年の agship級端末だと、最低でも: 4 to 10 cores CPU 3 to 4 GB memories largeHeap=true で512MB程度使える
  25. 25. Q. じゃあScala Android使うべき? 万人にオススメはしない  技術にはトレードオフがつきもの
  26. 26. Pros & Cons
  27. 27. Pros 豊富な言語機能とエコシステム ecosystem. 並行プログラミング コレクションAPI 代数的データ型とパターンマッチ トレイト 生産的 0.5 ~ 1.2 人で2年間新機能開発と運用まわしてました サーバーサイドもScalaだと頭の切り替え不要で楽
  28. 28. 他にScalaで嬉しい話 (View以外の)ステートレスな並行プログラミング Viewの修正はUIThreadで行うため、Viewについては排他制御を考える必要性が薄い
  29. 29. Scalaの並行プログラミングAPIは優秀 Scala標準のFuture悪くないですよ. UIThreadで実行するためのExecutionContextを定義して onComplete, andThen 等に明 示的に渡せる
  30. 30. UIExecutionContext Pattern class UIExecutionContext(activity:Activity, reporter: Throwable => Unit) extends ExecutionContext{ def execute(runnable: Runnable): Unit = activity.runOnUiThread(runnable) def reportFailure(t: Throwable): Unit = reporter(t) } Future{ //some heavy calculation }.onComplete{ case Success(result) => //reflect your result on views case Failure(exp) => //show error message }(uiExecutionContext) //Explicitly!
  31. 31. その他のScala Androidプロジェクトたち セプテーニ・オリジナル hits 6 million DLs! 47 Degrees Akkaモジュール有り. GANMA! 47deg/macroid 47deg/nine-cards-v2 47deg/scala-days-android pocorall/scaloid
  32. 32. Cons dexファイルあたり、メソッド数 64k の上限. Scala標準ライブラリのjarはちょっと大きすぎる. ProguardかMultiDexが必要. Java8 supportなし Android SDK toolchain はいまだ Java6+ 環境を対象. Akkaのバージョンは2.3.16まで。ただしEnd-of-Lifeのマーク付き. メモリ管理もある程度気にしたい GoogleもLightbend公式サポート無し
  33. 33. Proguard Proguardは使用されていないクラス、フィールド、メソッドを除くポストプロセシングツー ル. 使用されていない とは 参照されていない. Proguard はリフレクションを解しない. AkkaはリフレクションをPropsや.confで多用している. もしProguardが正しく設定されていなければ, NoClassDefFoundErrorないしは NoSuchMethodErrorが ランタイムに投げられる. Android Scalaをやる上でとても苦痛な作業.
  34. 34. とはいえ、Proguardの設定って最初から全部自分でやらなき ゃいけないのか? そんなことはない Scala標準のライブラリ用のProguard設定は組み込み済 akka.actor と akka.io パッケージについては作りました scala-android/sbt-android proguard-con g.txt for akka-actor v2.3.16
  35. 35. 新しいライブラリについて Proguardの設定を簡単にやる方法(手抜き編)
  36. 36. 実際とりあえず試すにはこれで十分 ライブラリが十分小さい限りにおいては. 例えば、Akkaについて同じ方法で設定するなら、proguard-con g.txtに以下の一行を足 す: -keep class akka.** { *; } 後でちゃんと設定しましょう メソッド数が64kを超えたタイミング. MultiDexで乗り切るという手もある アプリをリリースする直前にapkサイズを削りたいとき
  37. 37. Proguardの設定方法(推奨) リフレクションで参照されているクラスを調べよう grep -r "classOf" . が最も簡単 FQCN(フル修飾名)が.confファイルなどの設定ファイルに記述されているクラスを調べよ う. ラインタイムにNoClassDefFoundErrorや NoSuchMethodErrorを起こしたクラスを調べよう.
  38. 38. Proguard-Con gは最終的にこんな感じ: # Akka configuration # Akka 2.3.16 ## for akka.actor ### Classes used in reference.conf #### akka.actor.provider -keep class akka.actor.LocalActorRefProvider { *; } #### akka.actor.guardian-supervisor-strategy -keep class akka.actor.DefaultSupervisorStrategy { *; } #### akka.actor.mailbox -keep class akka.dispatch.UnboundedMailbox { *; } -keep class akka.dispatch.BoundedMailbox { *; } -keep class akka.dispatch.UnboundedDequeBasedMailbox { *; } -keep class akka.dispatch.BoundedDequeBasedMailbox { *; } #### akka.actor.mailbox.requirements -keep class akka.dispatch.BoundedDequeBasedMessageQueueSemantics { *; } -keep class akka.dispatch.UnboundedMessageQueueSemantics { *; } -keep class akka.dispatch.UnboundedDequeBasedMessageQueueSemantics { *; } -keep class akka.dispatch.DequeBasedMessageQueueSemantics { *; } -keep class akka.dispatch.MultipleConsumerSemantics { *; } #### akka.scheduler.implementation -keep class akka.actor.LightArrayRevolverScheduler { *; }
  39. 39. Proguardの設定でapkファイルのAPIメソッド数の比較 In akka.actor and akka.io 2.3.16 (and Scala 2.11.11) Proguard setting # of methods in dex APK size Akkaの全クラスを残す 35033 1132KB 15784 590KBAkkaのクラスのうち、リフレクション、confファイルからの 参照のみ残す 注意: レポジトリで比較した結果で、もちろんどの程度Akka, Scalaのクラスを利用す るかに寄って最終的な差は変わります サンプル
  40. 40. AndroidはJava8をサポートするのか? GoogleはAndroidのdex toolchainがJava8をサポートする旨アナウンスしている. Java 8 Language Features Support Update - Android Developers Blog とはいえ、Scalaと組み合わせてちゃんと動くのかはまだ分からない。
  41. 41. もしAndroidがJava8サポートしたら Scala 2.12以上 Scala標準ライブラリjarが小さく。 Dotty(Scala 3.0)が 由来のcallgraph analysisによって、dead codeをなく せるかも. (Proguardが不要に!) Akka Streams (Akka 2.4) ow graphの抽象化と, 扱いやすいback pressure管理。 Akka Typed (2.5) Backo Supervisor (2.4以上) Backo SupervisorとThreadLocalRandomをbackportすることもさほど難しくない Dotty-Linker
  42. 42. メモリ管理 Android GCはConcurrent Mark & Sweep. WrappedArray#mapやその他の高階関数はprimitive型をboxingすることがある 特にコピーが走りやすい場所ではring bu erが良い ByteStringはconcatenationとslicingに効率が良い 狭いスコープでmutableなオブジェクト/コレクションを使うのは悪くない選択肢. xuwei_k/nobox
  43. 43. 結論 ActorモデルはAndroidでもうまく働く。特に ステートフル な並行プログラミングにおいて。 Akkaの障害からの復旧力は(アウトドアのような)エラーの起きやすい環境では役立つ BONX AndroidアプリはAkkaの特長を活用してVoIPシステムを構築している.

×