23. 破滅のピラミッド
var g = ...
!
step1 { a =>
step2 { b =>
step3 { c =>
step4 { d =>
// do something with a, b, c, d and g
}
}
}
}
依存する非同期ステップが
ピラミッドのように積み上がる
外側のスコープの状態を暗黙に
参照していてモジュール性が低い
38. 例 (Akka Streams):
implicit val system = ActorSystem()
implicit val mat = ActorMaterializer()
!
val a = Source(...)
val b = Source(...)
!
val a1 = a.map(_ + 1)
val b1 = b.map(_ - 1).map(_ * 2)
!
val c = (a1 zip b1).map{case (a, b) => a + b}
!
c.runWith(Sink.foreach(println))(mat)
A
B C
+1
—1
×2
+
先ほどのデータフローを
関数型 DSL で記述する
39. 例 (Akka Streams):
implicit val system = ActorSystem()
implicit val mat = ActorMaterializer()
!
val a = Source(...)
val b = Source(...)
!
val a1 = a.map(_ + 1)
val b1 = b.map(_ - 1).map(_ * 2)
!
val c = (a1 zip b1).map{case (a, b) => a + b}
!
c.runWith(Sink.foreach(println))(mat)
入力に適用する関数を
高階関数 map で繋ぎ合わせる
関数
入力
A
B C
+1
—1
×2
+
43. 遅延評価
class Cons[A](hd: A, tl: => List[A]) extends List[A]
!
def nats(n: Int): List[Int] = new Cons(n, nats(n+1))
def fizzbuzz(n: Int) = n match {
case _ if n % 15 == 0 => "FizzBuzz"
case _ if n % 3 == 0 => "Fizz"
case _ if n % 5 == 0 => "Buzz"
case _ => n.toString
}
nats.map(fizzbuzz).take(100).foreach(println)
必要呼び
(プル型)
コードを生成器と選択器の
組み合わせでモジュール化できる
無限リスト
46. FRP の〈糊〉
implicit val system = ActorSystem()
implicit val mat = ActorMaterializer()
!
val a = Source(...)
val b = Source(...)
!
val a1 = a.map(_ + 1)
val b1 = b.map(_ - 1).map(_ * 2)
!
val c = (a1 zip b1).map{case (a, b) => a + b}
!
c.runWith(Sink.foreach(println))
A
B C
+1
—1
×2
+
生成器
非同期の文脈を局所化した高階関数 (map, zip 等)を使い、
ビジネスロジックをパイプライン化する
選択器
局所化された非同期の文脈
47. • 多くの FRP のデータフロー記述は宣言型 DSL:
構築したデータフローを実際にスケジュールし
実行するのはランタイムの役割
what と how の分離
implicit val system = ActorSystem()
implicit val mat = ActorMaterializer()
!
val c = (a1 zip b1).map{case (a, b) => a + b}
!
c.runWith(Sink.foreach(println))(mat) ランタイム
48. what と how の分離
Input
Input
Output(2) ランタイム
(1) プログラミングモデル (DSL)
(how を実行する = 変更の伝搬)
(what を記述する = データフロー)
52. 例: 融合 (Fusing)
• Akka Streams 2.0 の新機能
This new abstraction … is called fusing. This feature
… will be now possible to execute multiple stream
processing steps inside one actor, reducing the
number of thread-hops where they are not
necessary … will increase performance for various
use cases, including HTTP.
http://akka.io/news/2015/11/05/akka-streams-2.0-M1-released.html
複数の処理ステップを
一つにまとめて性能向上