Top Banner
Real World Android Akka
48

Real world android akka

Apr 16, 2017

Download

Software

Taisuke Oe
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Real world android akka

Real World Android Akka

Page 2: Real world android akka

Who am I?

麻植泰輔 / Taisuke OeTwitter: @OE_uiaGitHub: taisukeoe

会社

- BONX INC. でAndroidアプリ書いたりスノー

ボードするお仕事

- ScalaMatsuri座長 / Japan Scala Association, Inc.常務理事

個人

- Scalaを教える仕事しています

Page 3: Real world android akka

スポンサー募集CFPスタッフ募集

OPEN!!

Page 4: Real world android akka

What’s the topic?

本日のお話

Page 5: Real world android akka

本日のお話

Android

+

Scala

+

Akka

VoIPクライアント

Page 6: Real world android akka

本日のお話

◉ Akka○ メッセージ駆動○ Actorの実行モデル○ Actorのヒエラルキー

◉ BONX○ BONXとは?○ BONX VoIPクライアントの要求仕様

◉ Android Akkaの注意点○ Dispatcher, Mailboxの実装など

◉ Scala Androidってどうなの?

Page 7: Real world android akka

Akka?

Page 8: Real world android akka

Akka

◉ メッセージ駆動で並行/分散処理するtoolkit◉ Lightbend CTO Jonas Bonér氏が作者◉ 名前の由来はスイスの先住民の神様◉ スイスのLaponiaという山がAkka神のシンボル

Page 9: Real world android akka

Message Driven?

メッセージ駆動?

Page 10: Real world android akka

メッセージ駆動

Actorがメッセージを送り合い協調動作することで、システムを構成

あとはたのむ

Page 11: Real world android akka

メッセージ駆動

あとはたのむ次に手が空いてからやるわ

Actorが受け取ったメッセージは、そのActorに紐付いたMailboxに入る

Page 12: Real world android akka

メッセージ駆動

あとはたのむ次に手が空いてからやるわ

Actorはメッセージ一つ一つを逐次処理する

=> (特にスレッドセーフではない)状態管理を伴う並行プログラミングに有用

Page 13: Real world android akka

メッセージ駆動

あとはたのむ 今からやるお

Actorは他のActorについては、メッセージの送信先と受け取れるメッセージの種類についてのみ知っておけばよいため、Actor同士を疎結合にしやすい

Page 14: Real world android akka

Akka Dispatcher

Actorの実行モデル

Page 15: Real world android akka

Actorの実行モデル

Thread

ThreadDispatcher

DispatcherがActorの実行基盤。内部にThreadPoolを保持。

Page 16: Real world android akka

Actorの実行モデル

Thread

ThreadDispatcher

1つのActorは、同時に一つのスレッドにだけ割り振られる

Page 17: Real world android akka

Actorの実行モデル

Thread

ThreadDispatcher

Threadが空いたら、次のActorが割り振られる

Page 18: Real world android akka

Actorの実行モデルDispatcher

Actorは、Mailboxにメッセージが有り、なおかつThreadが割り当てられてるときにメッセージを処理する

Page 19: Real world android akka

Actorプログラミングのアンチパターン

Thread

ThreadDispatcher

Actorが長時間Threadをブロックすると、同じdispatcherを使用しているActorシステム全体の処理が進みにくくなる

進捗ダメです

Page 20: Real world android akka

Akka Actor Hierarchy

Actorのヒエラルキー

Page 21: Real world android akka

Actorの階層構造Dispatcher

Actorには親子関係が作れる

ワシが育てた

Page 22: Real world android akka

Actorの階層構造Dispatcher

子ActorでThrowableが投げられると、親ActorのsupervisorStrategy関数が呼ばれる

_人人人人人人人人人_

> 突然のThrowable < ̄Y^Y^Y^Y^Y^Y^Y^Y ̄

Page 23: Real world android akka

Actorの階層構造Dispatcher

supervisorStrategyの実装により、その後の子Actorの処遇が決定される

Restart

Page 24: Real world android akka

Akkaについて - まとめ

◉ Actorがメッセージを送り合うことでシステムを構成◉ 1つのActorは同時に1メッセージを1スレッドで逐次処

理するため、状態管理が楽◉ 実行モデル

○ Dispatcher … Thread(pool)の保持と、ActorへのThread貸出

○ Mailbox … Actorに送られたメッセージ置き場

◉ ActorのヒエラルキーとSupervisorStrategyの実装を適切に設定することで、障害からの回復力をもつ

Page 25: Real world android akka

The Way We Talk

BONX

Page 26: Real world android akka

BONXとは?

野外の激しい運動中でも

複数の仲間とスムーズに

コミュニケーションとれるVoIPサービス

VoIP = Voice over Internet Protocol

Page 27: Real world android akka
Page 28: Real world android akka

Requirement specification in BONX VoIP client

BONX VoIPクライアントの要求仕様

Page 29: Real world android akka

BONX VoIPクライアントの要求仕様

◉ 状態管理を伴う並行プログラミング

◉ (それなりに)低遅延

◉ 障害からの回復力

Page 30: Real world android akka

VoIPは音声ストリーム処理

ソケット通信録音 音量調整 発話検知 エンコード

デコード再生

Page 31: Real world android akka

音声ストリーム処理: 並行プログラミング

◉ 1フレームの処理が終わる前に、次のフレームの音声デー

タが送られてくる

◉ 必然的に並行プログラミングすることになる

◉ しかしエンコーダー・デコーダーなどのモジュールは、多く

の場合Threadセーフではない

Actorモデル向き

Page 32: Real world android akka

低遅延

◉ 合計の遅延:大きくなりすぎると、(特に顔が見えていると

き)通話中に違和感

◉ 個々の遅延:フレーム間の遅延が大きくなりすぎると、「ブ

ツッ」という音の途切れの原因

Dispatcher, Mailboxのカスタマイズ性は必要十分

Page 33: Real world android akka

障害からの回復力

◉ クライアントアプリとしては長時間(~8時間)の連続使用を想定

◉ 使用中、録音/再生のハードウェア I/Oなど一部のモジュールに問題が発生するケースがある

◉ 何かの状態がおかしい場合は、関連するモジュール含めて、自動で再初期化が必要

AkkaのActorヒエラルキーを適切に設定しておくと、モジュール群を自動で再初期化することで障害から回復できる

Page 34: Real world android akka

Pitfalls in Android Akka

Android Akkaの注意点

Page 35: Real world android akka

Android Akkaの注意点

◉ Akka version◉ Proguard設定◉ Dispatcherの罠◉ Mailboxのサイズ

Page 36: Real world android akka

Akka version

◉ AndroidはJava6/7相当の環境◉ Akka 2.14系はJava8要求

=> Akka 2.13系を使う

Page 37: Real world android akka

Proguard

● Akkaはapplication.confやPropsを基に、リフレクションでActorなどをインスタンス化

● Proguardは使用されていないクラス、メソッドをバイトコードから抜くpost-processingツール

● Proguardはリフレクションを理解しない● Android ScalaにおけるNoSuchMethodErrorの発生原因

の殆どはProguard起因

=> proguard.cfgに随時指定

参考: Macroid | Akka Integration

Page 38: Real world android akka

Dispatcherの罠

application.confのparallerism-factorは、(min~maxの範囲で)availableProcessorsに乗じた数のThreadPoolを作る

akka.dispatch.ThreadPoolConfig

object ThreadPoolConfig {/* … */ def scaledPoolSize(floor: Int, multiplier: Double, ceiling: Int): Int = math.min(math.max((Runtime.getRuntime.availableProcessors * multiplier).ceil.toInt, floor), ceiling)/* … */}

Page 39: Real world android akka

AndroidのavailableProcessorsAndroidの場合、電力消費を抑えるため、高クロックと低クロックのコアから構成されているヘテロCPUが主流。そのため、一度に全てのCPUコアがonlineにならない端末が多い。

しかしRuntime#availableProcessorsは常に全合計コア数を返す。この数字をそのまま使うと、Thread数がコア数に対して多くなりすぎてパフォーマンスが低下することがある

/sys/devices/system/cpu/online では 1-5,6 のようにオンライン状態のCPUのindexをチェックできる (参考:Linux kernel related to hotplug a CPU)

Page 40: Real world android akka

カスタムDispatcher

akka.dispatcher.ExecutorServiceConfiguratorを継承したクラスのFQCN(フル修飾名)をapplication.confに指定可能

my-dispatcher { type = Dispatcher executor = "com.taisukeoe.MyExecutorConfigurator" fork-join-executor { parallerism-min = 8 parallerism-factor = 2 parallerism-max = 16 }}

Page 41: Real world android akka

カスタムExecutorServiceConfigurator

class MyExecutorConfigurator(config: Config, prerequisites: DispatcherPrerequisites) extends ExecutorServiceConfigurator(config, prerequisites) {

final def createExecutorServiceFactory(id: String, threadFactory: ThreadFactory): ExecutorServiceFactory = {

val c = config.getConfig("fork-join-executor")

new ForkJoinExecutorServiceFactory( threadFactory.asInstanceOf[ForkJoinPool.ForkJoinWorkerThreadFactory], CPUConfig.scaledPoolSize( c.getInt("parallelism-min"), c.getDouble("parallelism-factor"), c.getInt("parallelism-max")), true) }}

Page 42: Real world android akka

OnlineのCPUコア数を取得

object CPUConfig { private lazy val rangeRegex = "([0-9]+)\\-([0-9]+)".r

def onlineProcessors: Option[Int] = Try { val reader = new BufferedReader(new FileReader("/sys/devices/system/cpu/online")) val num = Iterator.continually(reader.readLine()).takeWhile(_ != null).toSeq.headOption map { cpu:String => cpu.split(",").map { case rangeRegex(from, to) => to.toInt - from.toInt + 1 case num => 1 }.sum reader.close() num }}.toOption.flatten

def scaledPoolSize(floor: Int, multiplier: Double, ceiling: Int): Int =math.min(math.max(onlineProcessors.getOrElse(Runtime.getRuntime.availableProcessors) * multiplier).ceil.toInt, floor), ceiling)}

Page 43: Real world android akka

Mailboxのサイズ

◉ Androidは(増えてきたとはいえ)基本的には低メモリ環境◉ 1 VM ~ 数百MB RAM◉ サイズ制限のないMessageBoxだとOutOfMemoryErrorのおそれ◉ できるだけ有限サイズのMailbox (BoundedMailbox) を使う方が

良い◉ それで必要要件をみたさないときは、カスタムMailboxを作るべき

参考: Mailboxes -- Akka

my-mailbox { mailbox-type = "com.taisukeoe.MyMailBox"}

Page 44: Real world android akka

Android Scala Pros & Cons

ScalaでAndroidってどうなの?

Page 45: Real world android akka

ScalaでAndroidってどうなの?

◉ ScalaとAndroid両方に詳しい人がチームに1人いたら選択肢として

アリ。チーム2人目以降は、どちらかについて詳しければ、教育可能

◉ sbt-androidが(クセはあるけど)とても優秀。組み合わせると便利な

sbt pluginも色々

◉ 今回のケースではScala + Akka + Androidのメリットが存分に活き

○ 常時1~2人分の工数の少人数チームで新規機能開発&メンテ

○ 必要な低遅延/スループットなどのパフォーマンスを達成しつ

つ、モジュールの疎結合化、コードの抽象化に(それなりに)成功

Page 46: Real world android akka

ScalaでAndroidってどうなの?

◉ 万人にオススメはしない

◉ ScalaとAndroid両方の知識がそれなりに必要

◉ ビルドが長い (Proguardのせい)

◉ Googleのサポート外

○ Scala2.12 & Java8対応? ■ Jack & JillがJava8対象

○ Jack & Jill対応?

■ sbt-androidにPullReqは一応....

Page 47: Real world android akka

まとめ

◉ Akkaはメッセージ駆動で並行/分散処理を便利に行えるtoolkit

◉ Androidでも幾つかのポイントに注意すれば、Akkaは十分実用的である。

◉ VoIPアプリの音声ストリーム処理など、AndroidでもActorモデルが非常に有用となるケースがある

Page 48: Real world android akka

We’re hiring!

◉ VoIPクライアントアプリに興味がある人◉ Android Scalaを触ってみたい人◉ Akkaのチューニングをゴリゴリしたい人◉ スノボ、サイクリング 等々が好きな人

お気軽に @OE_uia までメッセください