SlideShare a Scribd company logo
Real World
Android Akka
Taisuke Oe
自己紹介?
麻植泰輔 / TaisukeOe
GitHub: / Twitter:
お仕事
セプテーニ・オリジナル 技術アドバイザーとしてPullReqレビュー/新卒研修
座長
taisukeoe @OE_uia
BONX Android App
ScalaMatsuri
次回のScalaMatsuri
2018年3月予定!
現在日程調整中。お楽しみに!
今日話すこと
VoIPクライアント
VoIP : Voice Over Internet Protocol
VoIPサンプル
taisukeoe/VoIPAkka
Real World Example
Real World Android Akka - 日本語版
Real World Android Akka - 日本語版
BONXとは?
アウトドア用の通話システム
スノーボード
スキー
釣り
サイクリング
...
BONXアーキテクチャ
アプリ
VoIPクライアント
Android : Scala
iOS : Objective C / Swift
サーバー
APIサーバー : Ruby on Rails
Voiceサーバー : golang
Bluetoothヘッドセット
Android Akkaを使ったワケ
VoIPはステートフルな非同期ストリーム処理
Upstream
Recorder -> some DSP -> Encoder -> Socket
Downstream
Socket -> Decoder -> some DSP -> Player
DSP : Digital Signal Processing
全てのコンポーネントは状態が有り、更に スレッドセーフではない.
求められる障害からの回復力(Resiliency).
アウトドアでは、様々なエラーに遭遇する
不安定なネットワーク
圏外<->圏内間の度重なる移動
ハードウェアI/Oエラー
Bluetooth切断
アウトドアで遊んでいる最中は画面操作できないので、自動復旧が肝。
更に悪いことに:
エラーは必ずしも問題のコンポーネントで捕捉されない。
下流で気づくことがある
すなわちエラーを逆方向に伝搬させたい
問題のあるコンポーネントは、壊れた音声データを生むかもしれない
そしてノイズの原因になりうる
すなわちエラーの種類によっては、キューにたまった音声データを消さなければいけない
(逆もまた然り)
まとめ: BONXの要求仕様
ステートフルな非同期ストリーム処理
障害からの回復力
そこでAkkaの出番!
Akkaは 並行プログラミング、障害からの自動回復
... そして分散システムを構築するためのtoolkit.
(ステートフルな) 並行プログラミングのために
メッセージ駆動なアクターモデル
アクターは、状態を内部に閉じ込めたまま、並行プログラミングが容易
状態を内部に閉じ込めた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()
}
}
Akkaによる障害からの回復力(Resiliency)
例外のハンドリング
Actorヒエラルキー
子アクターをsupervisorStrategyにもとづいてRestart, Stop, Resume
これによるRestartは メッセージボックスにメッセージを貯める.
モニタリング (Death watch)
監視対象のアクターがstopすると、監視側のアクターはTerminated(actorRef) メッセー
ジを受け取るので、そこで再生成する
これによるアクター再生性は メッセージボックス内のメッセージを破棄する.
アクターによる例外のハンドリングのサンプル
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
}
}
Recaps: なぜAkkaがうまく働いたのか
ステートフルな並行プログラミング
アクターの状態のカプセル化 / 一度に一つだけメッセージを処理するのでロック不要
障害からの回復力
アクターのヒエラルキーないしはモニタリングで管理
AkkaによってVoIP問題が「だいたい」解消した!
なぜ「だいたい」なのか ?
ものによっては例外として検知しにくい問題がある
オーディオドライバが場合によっては(ブロックしたまま)沈黙し、何も返さないことがある
銀の弾丸はない
Askパターンで、Ack が Timeout 内に返ってくるかチェック。
もし Ask がタイムアウトしたら、stopし再生成。
とはいえ、まずは「例外」として問題を検知する方法を探るべき
あまりオススメはしない
どうしてScalaがAndroidで使えるのか?
ビルドツールチェイン
scalac がScalaのソースをJava bytecodeにコンパイル
Android SDK の dex が Java bytecode を Dalvik Executable bytecodes に翻訳
Android標準のビルドシステムの主要機能は抑えている
sbt pluginと組み合わせ等が柔軟
scala-android/sbt-android
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 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!
その他のScala Androidプロジェクトたち
セプテーニ・オリジナル
hits 6 million DLs!
47 Degrees
Akkaモジュール有り.
GANMA!
47deg/macroid
47deg/nine-cards-v2
47deg/scala-days-android
pocorall/scaloid
Cons
dexファイルあたり、メソッド数 64k の上限.
Scala標準ライブラリのjarはちょっと大きすぎる.
ProguardかMultiDexが必要.
Java8 supportなし
Android SDK toolchain はいまだ Java6+ 環境を対象.
Akkaのバージョンは2.3.16まで。ただしEnd-of-Lifeのマーク付き.
メモリ管理もある程度気にしたい
GoogleもLightbend公式サポート無し
Proguard
Proguardは使用されていないクラス、フィールド、メソッドを除くポストプロセシングツー
ル.
使用されていない とは 参照されていない.
Proguard はリフレクションを解しない.
AkkaはリフレクションをPropsや.confで多用している.
もしProguardが正しく設定されていなければ, NoClassDefFoundErrorないしは
NoSuchMethodErrorが ランタイムに投げられる.
Android Scalaをやる上でとても苦痛な作業.
とはいえ、Proguardの設定って最初から全部自分でやらなき
ゃいけないのか?
そんなことはない
Scala標準のライブラリ用のProguard設定は組み込み済
akka.actor と akka.io パッケージについては作りました
scala-android/sbt-android
proguard-con g.txt for akka-actor v2.3.16
新しいライブラリについて
Proguardの設定を簡単にやる方法(手抜き編)
Real World Android Akka - 日本語版
実際とりあえず試すにはこれで十分
ライブラリが十分小さい限りにおいては.
例えば、Akkaについて同じ方法で設定するなら、proguard-con g.txtに以下の一行を足
す:
-keep class akka.** { *; }
後でちゃんと設定しましょう
メソッド数が64kを超えたタイミング.
MultiDexで乗り切るという手もある
アプリをリリースする直前にapkサイズを削りたいとき
Proguardの設定方法(推奨)
リフレクションで参照されているクラスを調べよう
grep -r "classOf" . が最も簡単
FQCN(フル修飾名)が.confファイルなどの設定ファイルに記述されているクラスを調べよ
う.
ラインタイムにNoClassDefFoundErrorや NoSuchMethodErrorを起こしたクラスを調べよう.
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 { *; }
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のクラスを利用す
るかに寄って最終的な差は変わります
サンプル
AndroidはJava8をサポートするのか?
GoogleはAndroidのdex toolchainがJava8をサポートする旨アナウンスしている.
Java 8 Language Features Support Update - Android Developers Blog
とはいえ、Scalaと組み合わせてちゃんと動くのかはまだ分からない。
もし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
メモリ管理
Android GCはConcurrent Mark & Sweep.
WrappedArray#mapやその他の高階関数はprimitive型をboxingすることがある
特にコピーが走りやすい場所ではring bu erが良い
ByteStringはconcatenationとslicingに効率が良い
狭いスコープでmutableなオブジェクト/コレクションを使うのは悪くない選択肢.
xuwei_k/nobox
結論
ActorモデルはAndroidでもうまく働く。特に ステートフル な並行プログラミングにおいて。
Akkaの障害からの復旧力は(アウトドアのような)エラーの起きやすい環境では役立つ
BONX AndroidアプリはAkkaの特長を活用してVoIPシステムを構築している.

More Related Content

PDF
Real world android akka
PDF
Quarkus による超音速な Spring アプリケーション開発
PPTX
Akka actorを何故使うのか?
PDF
WebSocket+Akka(Remote)+Play 2.1 Java
PPTX
Javaにおけるネイティブコード連携の各種手法の紹介
PDF
私たちはRESTCONFでネットワーク自動化的に何が嬉しくなるのか考えてみた
PPTX
kubernetes初心者がKnative Lambda Runtime触ってみた(Kubernetes Novice Tokyo #13 発表資料)
PDF
ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催)
Real world android akka
Quarkus による超音速な Spring アプリケーション開発
Akka actorを何故使うのか?
WebSocket+Akka(Remote)+Play 2.1 Java
Javaにおけるネイティブコード連携の各種手法の紹介
私たちはRESTCONFでネットワーク自動化的に何が嬉しくなるのか考えてみた
kubernetes初心者がKnative Lambda Runtime触ってみた(Kubernetes Novice Tokyo #13 発表資料)
ネットワーク自動化、なに使う? ~自動化ツール紹介~(2017/08/18追加開催)

What's hot (20)

PDF
仕様をコードに落としこむ際気をつけたいこと
PPTX
Akkaの翻訳みんなでやろう Let's translate akka doc
PDF
AWSで開発するサーバレスAPIバックエンド
PDF
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
PPTX
Java on Azure 2019
PPTX
AKS (k8s) Hands on Lab Contents
PPTX
[OpenStack Days Tokyo 2015] Zabbixを用いたOCPベアメタル監視環境構築の自働化
PDF
Quarkus入門
PDF
Ansible ネットワーク自動化チュートリアル (JANOG42)
PDF
プログラミング言語のパラダイムシフト(ダイジェスト)ーScalaから見る関数型と並列性時代の幕開けー
PDF
Spring Framework ふりかえりと4.3新機能
PDF
OpenStack APIを使った新しいアプリケーションモデル
PPT
Webサーバの基礎知識【編集済み】
PDF
How to contribute AWX
PDF
Akka meetup 2014_sep
PPTX
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
PDF
ログについて改めて考えてみた
PPTX
Jjug CCC 2019 Fall Azure Spring Cloud
PDF
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon
仕様をコードに落としこむ際気をつけたいこと
Akkaの翻訳みんなでやろう Let's translate akka doc
AWSで開発するサーバレスAPIバックエンド
Reactive Webアプリケーション - そしてSpring 5へ #jjug_ccc #ccc_ef3
Java on Azure 2019
AKS (k8s) Hands on Lab Contents
[OpenStack Days Tokyo 2015] Zabbixを用いたOCPベアメタル監視環境構築の自働化
Quarkus入門
Ansible ネットワーク自動化チュートリアル (JANOG42)
プログラミング言語のパラダイムシフト(ダイジェスト)ーScalaから見る関数型と並列性時代の幕開けー
Spring Framework ふりかえりと4.3新機能
OpenStack APIを使った新しいアプリケーションモデル
Webサーバの基礎知識【編集済み】
How to contribute AWX
Akka meetup 2014_sep
CEDEC2021 ダウンロード時間を大幅減!~大量のアセットをさばく高速な実装と運用事例の共有~
ログについて改めて考えてみた
Jjug CCC 2019 Fall Azure Spring Cloud
Seasar ユーザだったプログラマが目指す OSS の世界展開 #seasarcon
Ad

Similar to Real World Android Akka - 日本語版 (20)

PDF
ScalaでAndroidアプリ開発
PDF
第1回名古屋Android勉強会Lt用資料
PPTX
サクサクアンドロイド
PDF
Scala conf2013
PDF
JavaからAkkaハンズオン
KEY
2012 09-26-scala
KEY
関ジャバ JavaOne Tokyo 2012報告会
PDF
All I learned while working on a Scala OSS project for over six years #ScalaM...
PDF
【2018/09/11】PAYでのReact Nativeにおける APIクライアント実装 について
PDF
ATN No.2 Scala事始め
PDF
並列対決 Elixir × Go × C# x Scala , Node.js
PDF
言語アップデート -Scala編-
PPTX
つぶLT20121215
ODP
Next Language Scala
PDF
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
PDF
Scala EE 7 Essentials
PDF
Akkaで分散システム入門
PDF
ICT ERA + ABC 2012 Tohoku
PDF
Overview of Scala ~ Hacker Tackle
PDF
Play jjug2012spring
ScalaでAndroidアプリ開発
第1回名古屋Android勉強会Lt用資料
サクサクアンドロイド
Scala conf2013
JavaからAkkaハンズオン
2012 09-26-scala
関ジャバ JavaOne Tokyo 2012報告会
All I learned while working on a Scala OSS project for over six years #ScalaM...
【2018/09/11】PAYでのReact Nativeにおける APIクライアント実装 について
ATN No.2 Scala事始め
並列対決 Elixir × Go × C# x Scala , Node.js
言語アップデート -Scala編-
つぶLT20121215
Next Language Scala
プログラミング言語のパラダイムシフトーScalaから見る関数型と並列性時代の幕開けー
Scala EE 7 Essentials
Akkaで分散システム入門
ICT ERA + ABC 2012 Tohoku
Overview of Scala ~ Hacker Tackle
Play jjug2012spring
Ad

More from Taisuke Oe (10)

PDF
プレScalaMatsuri2019「スピーカー入門」
PDF
How to start functional programming (in Scala): Day1
PDF
Monix Taskが便利だという話
PDF
How to get along with implicits
PDF
What Dotty fixes @ Scala関西サミット
PDF
AuxパターンをDottyで解決する
PDF
Real World Android Akka
PDF
多相な関数の定義から学ぶ、型クラスデザインパターン
PDF
Android BLEのつらみを予防するTips
PDF
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~
プレScalaMatsuri2019「スピーカー入門」
How to start functional programming (in Scala): Day1
Monix Taskが便利だという話
How to get along with implicits
What Dotty fixes @ Scala関西サミット
AuxパターンをDottyで解決する
Real World Android Akka
多相な関数の定義から学ぶ、型クラスデザインパターン
Android BLEのつらみを予防するTips
BONXを支える技術:Bluetooth編 ~Bluetoothを120%使い倒す方法~

Real World Android Akka - 日本語版