Reactive Streams / Akka Streams - GeeCON Prague 2014

124
Konrad 'ktoso' Malawski GeeCON 2014 @ Kraków, PL Konrad `@ktosopl` Malawski Akka Streams OST: Tomas Dvorak ./‘ ./‘

description

Talk explaining the core concepts behind reactive streams.

Transcript of Reactive Streams / Akka Streams - GeeCON Prague 2014

Page 1: Reactive Streams / Akka Streams - GeeCON Prague 2014

Konrad 'ktoso' MalawskiGeeCON 2014 @ Kraków, PL

Konrad `@ktosopl` Malawski

Akka Streams

OST: Tomas Dvorak ./‘ ./‘

Page 2: Reactive Streams / Akka Streams - GeeCON Prague 2014

Konrad `@ktosopl` Malawski Akka Team,

Reactive Streams TCK

hAkker @

Page 3: Reactive Streams / Akka Streams - GeeCON Prague 2014

Konrad `@ktosopl` Malawski

typesafe.comgeecon.org

Java.pl / KrakowScala.plsckrk.com / meetup.com/Paper-Cup @ London

GDGKrakow.pl meetup.com/Lambda-Lounge-Krakow

hAkker @

Page 4: Reactive Streams / Akka Streams - GeeCON Prague 2014

You?

?

Page 5: Reactive Streams / Akka Streams - GeeCON Prague 2014

Czech User Group?

You?

Page 6: Reactive Streams / Akka Streams - GeeCON Prague 2014

You?

?

z ?

Page 7: Reactive Streams / Akka Streams - GeeCON Prague 2014

You?

?

z ?

?

Page 8: Reactive Streams / Akka Streams - GeeCON Prague 2014

You?

?

z ?

?

?

Page 9: Reactive Streams / Akka Streams - GeeCON Prague 2014

Streams

Page 10: Reactive Streams / Akka Streams - GeeCON Prague 2014

Streams

Page 11: Reactive Streams / Akka Streams - GeeCON Prague 2014

Streams“You cannot enter the same river twice”

~ Heraclitus

http://en.wikiquote.org/wiki/Heraclitus

Page 12: Reactive Streams / Akka Streams - GeeCON Prague 2014

StreamsReal Time Stream Processing

When you attach “late” to a Publisher,you may miss initial elements – it’s a river of data.

http://en.wikiquote.org/wiki/Heraclitus

Page 13: Reactive Streams / Akka Streams - GeeCON Prague 2014

Reactive Streams

Page 14: Reactive Streams / Akka Streams - GeeCON Prague 2014

Reactive Streams

Stream processing

Page 15: Reactive Streams / Akka Streams - GeeCON Prague 2014

Reactive Streams

Back-pressured

Stream processing

Page 16: Reactive Streams / Akka Streams - GeeCON Prague 2014

Reactive Streams

Back-pressured Asynchronous

Stream processing

Page 17: Reactive Streams / Akka Streams - GeeCON Prague 2014

Reactive Streams

Back-pressured Asynchronous

Stream processing Standardised (!)

Page 18: Reactive Streams / Akka Streams - GeeCON Prague 2014

Reactive Streams: Goals

1. Back-pressured Asynchronous Stream processing

2. Standard implemented by many libraries

Page 19: Reactive Streams / Akka Streams - GeeCON Prague 2014

Reactive Streams - Specification & TCK

http://reactive-streams.org

Page 20: Reactive Streams / Akka Streams - GeeCON Prague 2014

Reactive Streams - Who?

http://reactive-streams.org

Kaazing Corp.rxJava @ Netflix,

reactor @ Pivotal (SpringSource),vert.x @ Red Hat,

Twitter,akka-streams @ Typesafe,

spray @ Spray.io,Oracle,

java (?) – Doug Lea - SUNY Oswego …

Page 21: Reactive Streams / Akka Streams - GeeCON Prague 2014

Reactive Streams - Inter-op

http://reactive-streams.org

We want to make different implementations co-operate with each other.

Page 22: Reactive Streams / Akka Streams - GeeCON Prague 2014

Reactive Streams - Inter-op

http://reactive-streams.org

The different implementations “talk to each other”using the Reactive Streams protocol.

Page 23: Reactive Streams / Akka Streams - GeeCON Prague 2014

Reactive Streams - Inter-op

http://reactive-streams.org

The Reactive Streams SPI is NOT meant to be user-api.You should use one of the implementing libraries.

Page 24: Reactive Streams / Akka Streams - GeeCON Prague 2014

What is back-pressure?

Page 25: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Example Without

Publisher[T] Subscriber[T]

Page 26: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Example Without

Fast Publisher Slow Subscriber

Page 27: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure?“Why would I need that!?”

Page 28: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Push + NACK model

Page 29: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Push + NACK model

Subscriber usually has some kind of buffer.

Page 30: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Push + NACK model

Page 31: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Push + NACK model

Page 32: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Push + NACK model

What if the buffer overflows?

Page 33: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Push + NACK model (a)

Use bounded buffer, drop messages + require re-sending

Page 34: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Push + NACK model (a)

Kernel does this!Routers do this!

(TCP)

Use bounded buffer, drop messages + require re-sending

Page 35: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Push + NACK model (b)Increase buffer size… Well, while you have memory available!

Page 36: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Push + NACK model (b)

Page 37: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure?NACKing is NOT enough.

Page 38: Reactive Streams / Akka Streams - GeeCON Prague 2014

Negative ACKnowledgement

Page 39: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Example NACKingBuffer overflow is imminent!

Page 40: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Example NACKingTelling the Publisher to slow down / stop sending…

Page 41: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Example NACKingNACK did not make it in time,

because M was in-flight!

Page 42: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure?

speed(publisher) < speed(subscriber)

Page 43: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? Fast Subscriber, No Problem

No problem!

Page 44: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure?Reactive-Streams

= “Dynamic Push/Pull”

Page 45: Reactive Streams / Akka Streams - GeeCON Prague 2014

Just push – not safe when Slow Subscriber

Just pull – too slow when Fast Subscriber

Back-pressure? RS: Dynamic Push/Pull

Page 46: Reactive Streams / Akka Streams - GeeCON Prague 2014

Solution:Dynamic adjustment

Back-pressure? RS: Dynamic Push/Pull

Just push – not safe when Slow Subscriber

Just pull – too slow when Fast Subscriber

Page 47: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? RS: Dynamic Push/PullSlow Subscriber sees it’s buffer can take 3 elements. Publisher will never blow up it’s buffer.

Page 48: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? RS: Dynamic Push/PullFast Publisher will send at-most 3 elements. This is pull-based-backpressure.

Page 49: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? RS: Dynamic Push/Pull

Fast Subscriber can issue more Request(n), before more data arrives!

Page 50: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? RS: Dynamic Push/PullFast Subscriber can issue more Request(n), before more data arrives.

Publisher can accumulate demand.

Page 51: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? RS: Accumulate demandPublisher accumulates total demand per subscriber.

Page 52: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? RS: Accumulate demandTotal demand of elements is safe to publish. Subscriber’s buffer will not overflow.

Page 53: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? RS: Requesting “a lot”Fast Subscriber can issue arbitrary large requests, including “gimme all you got” (Long.MaxValue)

Page 54: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? RS: Dynamic Push/Pull

MAX

speed

Page 55: Reactive Streams / Akka Streams - GeeCON Prague 2014

Back-pressure? RS: Dynamic Push/Pull

Easy

MAX

speed

Page 56: Reactive Streams / Akka Streams - GeeCON Prague 2014

How does fit all this?

Page 57: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka

Akka has multiple modules:

akka-actor: actors (concurrency abstraction)akka-camel: integrationakka-remote: remote actorsakka-cluster: clusteringakka-persistence: CQRS / Event Sourcingakka-streams: stream processing…

Page 58: Reactive Streams / Akka Streams - GeeCON Prague 2014

AkkaAkka is a high-performance concurrency library for Scala and Java.

At it’s core it focuses on the Actor Model:

Page 59: Reactive Streams / Akka Streams - GeeCON Prague 2014

An Actor can only: • Send and receive messages• Create Actors• Change it’s behaviour

AkkaAkka is a high-performance concurrency library for Scala and Java.

At it’s core it focuses on the Actor Model:

Page 60: Reactive Streams / Akka Streams - GeeCON Prague 2014

class Player extends Actor {

def receive = { case NextTurn => sender() ! decideOnMove() }

def decideOnMove(): Move = ???}

Akka

Page 61: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka

Akka has multiple modules:

akka-actor: actors (concurrency abstraction)akka-camel: integrationakka-remote: remote actorsakka-cluster: clusteringakka-persistence: CQRS / Event Sourcingakka-streams: stream processing…

Page 62: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams0.9 early preview

Page 63: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

Page 64: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

Page 65: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

Page 66: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

Page 67: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

Flow[Double].map(_.toInt). [...]

No Source attached yet.“Pipe ready to work with Doubles”.

Page 68: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

implicit val sys = ActorSystem("tokyo-sys")

An ActorSystem is the world in which Actors live in.AkkaStreams uses Actors, so it needs ActorSystem.

Page 69: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

implicit val sys = ActorSystem("tokyo-sys")implicit val mat = FlowMaterializer()

Contains logic on HOW to materialise the stream.

Page 70: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

implicit val sys = ActorSystem("tokyo-sys")implicit val mat = FlowMaterializer()

A materialiser chooses HOW to materialise a Stream.

The Flow’s AST is fully “lifted”.The Materialiser can choose to materialise the Flow in any way it sees fit.

Our implementation uses Actors.But you could easily plug in an SparkMaterializer!

Page 71: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

implicit val sys = ActorSystem("tokyo-sys")implicit val mat = FlowMaterializer()

You can configure it’s buffer sizes etc.

Page 72: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

implicit val sys = ActorSystem("tokyo-sys")implicit val mat = FlowMaterializer()

val foreachSink = Sink.foreach[Int](println)val mf = Source(1 to 3).runWith(foreachSink)

Page 73: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

implicit val sys = ActorSystem("tokyo-sys")implicit val mat = FlowMaterializer()

val foreachSink = Sink.foreach[Int](println)val mf = FlowFrom(1 to 3).runWith(foreachSink)(mat)

Uses the implicit FlowMaterializer

Page 74: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

implicit val sys = ActorSystem("tokyo-sys")implicit val mat = FlowMaterializer()

// sugar for runWithSource(1 to 3).foreach(println)

Page 75: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

val mf = Flow[Int]. map(_ * 2). runWith(Sink.foreach(println)) // is missing a Source, // can NOT run == won’t compile!

Page 76: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

val f = Flow[Int]. map(_ * 2).

runWith(Sink.foreach(i => println(s"i = $i”))). // needs Source to run!

Page 77: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

val f = Flow[Int]. map(_ * 2).

runWith(Sink.foreach(i => println(s"i = $i”))). // needs Source to run!

Page 78: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

val f = Flow[Int]. map(_ * 2).

runWith(Sink.foreach(i => println(s"i = $i”))). // needs Source to run!

Page 79: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

val f = Flow[Int]. map(_ * 2).

runWith(Sink.foreach(i => println(s"i = $i”))). // needs Source to run!

f.connect(Source(1 to 10)).run()

Page 80: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

val f = Flow[Int]. map(_ * 2).

runWith(Sink.foreach(i => println(s"i = $i”))). // needs Source to run!

f.connect(Source(1 to 10)).run()

With a Source attached… it can run()

Page 81: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Linear Flow

Flow[Int]. map(_.toString). runWith(Source(1 to 10), Sink.ignore)

Connects Source and Sink, then runs

Page 82: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – Flows are reusable

f.withSource(IterableSource(1 to 10)).run() f.withSource(IterableSource(1 to 100)).run() f.withSource(IterableSource(1 to 1000)).run()

Page 83: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams <-> Actors – Advanced

val subscriber = ActorSubscriber( system.actorOf(Props[SubStreamParent], ”parent”))

Source(1 to 100). map(_.toString). filter(_.length == 2). drop(2). groupBy(_.last). runWith(subscriber)

Page 84: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams <-> Actors – Advanced

Each “group” is a stream too! It’s a “Stream of Streams”.

val subscriber = ActorSubscriber( system.actorOf(Props[SubStreamParent], ”parent”))

Source(1 to 100). map(_.toString). filter(_.length == 2). drop(2). groupBy(_.last). runWith(subscriber)

Page 85: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams <-> Actors – Advanced

groupBy(_.last).

GroupBy groups “11” to group “1”, “12” to group “2” etc.

Page 86: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams <-> Actors – Advanced

groupBy(_.last).

It offers (groupKey, subStreamSource) to Subscriber

Source

Page 87: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams <-> Actors – Advanced

groupBy(_.last).

It can then start children, to handle the sub-flows!

Source

Page 88: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams <-> Actors – Advanced

groupBy(_.last).

For example, one child for each group.

Source

Page 89: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams <-> Actors – Advanced

val subscriber = ActorSubscriber( system.actorOf(Props[SubStreamParent], ”parent”))

Source(1 to 100). map(_.toString). filter(_.length == 2). drop(2). groupBy(_.last). runWith(subscriber)

The Actor, will consume SubStream offers.

Page 90: Reactive Streams / Akka Streams - GeeCON Prague 2014

Consuming streams with Actors(advanced)

Page 91: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams <-> Actors – Advanced

class SubStreamParent extends ActorSubscriber with ImplicitFlowMaterializer with ActorLogging {

override def requestStrategy = OneByOneRequestStrategy

override def receive = { case OnNext((groupId: String, subStream: Source[String])) =>

val subSub = context.actorOf(Props[SubStreamSubscriber], s"sub-$groupId") subStream.runWith(Sink.subscriber(ActorSubscriber(subSub))) }}

Page 92: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams <-> Actors – Advanced

class SubStreamParent extends ActorSubscriber with ImplicitFlowMaterializer with ActorLogging {

override def requestStrategy = OneByOneRequestStrategy

override def receive = { case OnNext((groupId: String, subStream: Source[String])) =>

val subSub = context.actorOf(Props[SubStreamSubscriber], s"sub-$groupId") subStream.runWith(Sink.subscriber(ActorSubscriber(subSub))) }}

Page 93: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams <-> Actors – Advanced

class SubStreamParent extends ActorSubscriber with ImplicitFlowMaterializer with ActorLogging {

override def requestStrategy = OneByOneRequestStrategy

override def receive = { case OnNext((groupId: String, subStream: Source[String])) =>

val subSub = context.actorOf(Props[SubStreamSubscriber], s"sub-$groupId") subStream.runWith(Sink.subscriber(ActorSubscriber(subSub))) }}

Page 94: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams <-> Actors – Advanced

class SubStreamParent extends ActorSubscriber with ImplicitFlowMaterializer with ActorLogging {

override def requestStrategy = OneByOneRequestStrategy

override def receive = { case OnNext((groupId: String, subStream: Source[String])) =>

val subSub = context.actorOf(Props[SubStreamSubscriber], s"sub-$groupId") subStream.runWith(Sink.subscriber(ActorSubscriber(subSub))) }}

Page 95: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams <-> Actors – Advanced

class SubStreamParent extends ActorSubscriber with ImplicitFlowMaterializer with ActorLogging {

override def requestStrategy = OneByOneRequestStrategy

override def receive = { case OnNext((groupId: String, subStream: Source[String])) =>

val subSub = context.actorOf(Props[SubStreamSubscriber], s"sub-$groupId") subStream.runWith(Sink.subscriber(ActorSubscriber(subSub))) }}

Page 96: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams <-> Actors – Advanced

class SubStreamParent extends ActorSubscriber {

override def requestStrategy = WatermarkRequestStrategy(highWatermark = 10)

override def receive = { case OnNext(n: String) => println(s”n = $n”) }}

Page 97: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams <-> Actors – Advanced

class SubStreamParent extends ActorSubscriber {

override def requestStrategy = WatermarkRequestStrategy(highWatermark = 10)

override def receive = { case OnNext(n: String) => println(s”n = $n”) }}

Page 98: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – FlowGraph

FlowGraph

Page 99: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – FlowGraph

Linear Flows or

non-akka pipelines

Could be another RS implementation!

Page 100: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – GraphFlow

Fan-out elements and

Fan-in elements

Page 101: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – GraphFlow

// first define some pipeline piecesval f1 = Flow[Input].map(_.toIntermediate)val f2 = Flow[Intermediate].map(_.enrich)val f3 = Flow[Enriched].filter(_.isImportant)val f4 = Flow[Intermediate].mapFuture(_.enrichAsync)

// then add input and output placeholdersval in = SubscriberSource[Input]val out = PublisherSink[Enriched]

Page 102: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – GraphFlow

Page 103: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – GraphFlowval b3 = Broadcast[Int]("b3")val b7 = Broadcast[Int]("b7")val b11 = Broadcast[Int]("b11")val m8 = Merge[Int]("m8")val m9 = Merge[Int]("m9")val m10 = Merge[Int]("m10")val m11 = Merge[Int]("m11")val in3 = Source(List(3))val in5 = Source(List(5))val in7 = Source(List(7))

Page 104: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – GraphFlow

Page 105: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – GraphFlow

// First layerin7 ~> b7b7 ~> m11b7 ~> m8

in5 ~> m11

in3 ~> b3b3 ~> m8b3 ~> m10

Page 106: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – GraphFlow

// Second layerm11 ~> b11b11 ~> Flow[Int].grouped(1000) ~> resultFuture2 b11 ~> m9b11 ~> m10

m8 ~> m9

Page 107: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – GraphFlow

// Third layerm9 ~> Flow[Int].grouped(1000) ~> resultFuture9m10 ~> Flow[Int].grouped(1000) ~> resultFuture10

Page 108: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – GraphFlow

// Third layerm9 ~> Flow[Int].grouped(1000) ~> resultFuture9m10 ~> Flow[Int].grouped(1000) ~> resultFuture10

Page 109: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – GraphFlow

// Third layerm9 ~> Flow[Int].grouped(1000) ~> resultFuture9m10 ~> Flow[Int].grouped(1000) ~> resultFuture10

Page 110: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – GraphFlow

val resultFuture2 = Sink.future[Seq[Int]]val resultFuture9 = Sink.future[Seq[Int]]val resultFuture10 = Sink.future[Seq[Int]]

val g = FlowGraph { implicit b => // ... m10 ~> Flow[Int].grouped(1000) ~> resultFuture10 // ...}.run()

Await.result(g.get(resultFuture2), 3.seconds).sorted should be(List(5, 7))

Sinks and Sources are “keys”which can be addressed within the graph

Page 111: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – GraphFlow

val resultFuture2 = Sink.future[Seq[Int]]val resultFuture9 = Sink.future[Seq[Int]]val resultFuture10 = Sink.future[Seq[Int]]

val g = FlowGraph { implicit b => // ... m10 ~> Flow[Int].grouped(1000) ~> resultFuture10 // ...}.run()

Await.result(g.get(resultFuture2), 3.seconds).sorted should be(List(5, 7))

Sinks and Sources are “keys”which can be addressed within the graph

Page 112: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka Streams – GraphFlow

val g = FlowGraph {}

FlowGraph is immutable and safe to share and re-use!

Page 113: Reactive Streams / Akka Streams - GeeCON Prague 2014

Available Elements0.9 early preview

Page 114: Reactive Streams / Akka Streams - GeeCON Prague 2014

Available Sources• FutureSource• IterableSource• IteratorSource• PublisherSource• SubscriberSource• ThunkSource• TickSource (timer based)• … easy to add your own!

0.9 early preview

Page 115: Reactive Streams / Akka Streams - GeeCON Prague 2014

Available operations• drop / dropWithin• take / takeWithin• filter• groupBy• grouped• map• prefixAndTail• … easy to add your own!

0.9 early preview

“Rate – detaching” operations:• buffer• collect• concat• conflate

Page 116: Reactive Streams / Akka Streams - GeeCON Prague 2014

Available Sinks• BlackHoleSink• FoldSink• ForeachSink• FutureSink• OnCompleteSink• PublisherSink / FanoutPublisherSink• SubscriberSink• … easy to add your own!

0.9 early preview

Page 117: Reactive Streams / Akka Streams - GeeCON Prague 2014

Available Junctions• Broadcast• Merge

• FlexiMerge• Zip• Unzip• Concat• … easy to add your own!

0.9 early preview

Page 118: Reactive Streams / Akka Streams - GeeCON Prague 2014

Akka-StreamsComing soon!

Page 119: Reactive Streams / Akka Streams - GeeCON Prague 2014

Rough plans

• 0.9 released

• 0.10 in 2~3 weeks

• 1.0 “soon” after…• Means “stabilised APIs”• Will not yet be performance tuned, though it’s already

pretty good… we know where and how we can tune it for 1.x.

0.7 early preview

Page 120: Reactive Streams / Akka Streams - GeeCON Prague 2014

Java DSL

• Partial Java DSL in 0.9 (released)

• Full Java DSL in 0.10 (in 2~3 weeks)• as 1st class citizen (!)

0.7 early preview

Page 121: Reactive Streams / Akka Streams - GeeCON Prague 2014

Spray => Akka-Http && ReactiveStreams

Spray is now merged into Akka, as Akka-HttpWorks on Reactive Streams

Streaming end-to-end!

Page 122: Reactive Streams / Akka Streams - GeeCON Prague 2014

Links• http://akka.io • http://reactive-streams.org

• https://groups.google.com/group/akka-user

• 0.7 release http://akka.io/news/2014/09/12/akka-streams-0.7-released.html

• javadsl https://github.com/akka/akka/pulls?q=is%3Apr+javadsl

Page 123: Reactive Streams / Akka Streams - GeeCON Prague 2014

Děkuji vám!Dzięki!ありがとう!Ask questions,get Stickers! (for real!)

http://akka.io

ktoso @ typesafe.com twitter: ktosoplgithub: ktosoteam blog: letitcrash.com

Page 124: Reactive Streams / Akka Streams - GeeCON Prague 2014

©Typesafe 2014 – All Rights Reserved