Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

Reactive Streams and Akka Streams Markus Jura (@markusjura) & Lutz Huehnken (@lutzhuehnken)

Slide 3

Slide 3 text

Streams

Slide 4

Slide 4 text

Reactive Streams Common Use of Streams • Bulk Data Transfer • Real Time Data Sources • Batch Processing of large data sets • Monitoring and Analytics 4

Slide 5

Slide 5 text

Reactive Streams What is a Stream? • Ephemeral flow of data • Potentially unbounded in size • Processed by describing transformation of data 5

Slide 6

Slide 6 text

Reactive Streams

Slide 7

Slide 7 text

Reactive Streams Reactive Streams Projects / Companies • Typesafe • Akka Streams • Netflix • rxJava / rxScala • Pivotal • Spring Reactor • Redhat • Vert.x • Oracle 7

Slide 8

Slide 8 text

Reactive Streams Reactive 8

Slide 9

Slide 9 text

Reactive Streams Reactive Streams Overview • How do we: • Handle potentially infinite streams of data? • Handle data in a reactive manner? • Achieve asynchronous non-blocking data flow? • Avoid out of memory errors? 9

Slide 10

Slide 10 text

Reactive Streams Supply and Demand • Data Items Flow Downstream • Demand Flows Upstream • Data Items flow only when there is demand. 10

Slide 11

Slide 11 text

Reactive Streams Dynamic Push-Pull • “Push” behavior when consumer is faster • “Pull” behavior when producer is faster • Switches automatically between these • Batching demand allows batching data 11

Slide 12

Slide 12 text

Reactive Streams Reactive Streams Specification • Interface Specification • Java interfaces for implementations • TCK • Test Harness to validate implementations • Specification Website • http://www.reactive-streams.org/ 12

Slide 13

Slide 13 text

Reactive Streams Publisher package org.reactivestreams; public interface Subscriber {...} public interface Publisher { public void subscribe( Subscriber subscriber); } 13

Slide 14

Slide 14 text

Reactive Streams Subscriber public interface Subscriber { public void onSubscribe( Subscription subscription); public void onNext(T element); public void onComplete(); public void onError(Throwable cause); } 14

Slide 15

Slide 15 text

Reactive Streams Subscription public interface Subscription { public void cancel(); public void request(long elements); } 15

Slide 16

Slide 16 text

Reactive Streams Backpressure • Downstream consumers pushing back on the producer to prevent flooding. • In reactive-streams: • Consumers stop requesting more elements until they are ready to process more. • Producers only fire elements if there is demand. 16

Slide 17

Slide 17 text

Reactive Streams Why Backpressure? • Explicitly design for system overload • Demand is propagated throughout the WHOLE flow • Can decide WHERE to handle overload • Limit the number of in-flight messages throughout the system • Bounded memory consumption • Bounded cpu contention • Recipient is in control of incoming data rate • Data in flight is bounded by signaled demand 17

Slide 18

Slide 18 text

Reactive Streams Buffering • We can prefetch stream elements by requesting more than we really need. • We can use this technique to ensure no "sputter" in the stream. • We can also use this technique to pull faster than downstream consumer. 18

Slide 19

Slide 19 text

Akka Streams & Actors

Slide 20

Slide 20 text

Reactive Streams Basic Actor 20 case class Greeting(who: String) class GreetingActor extends Actor with ActorLogging { def receive = { case Greeting(who) => log.info("Hello " + who) } } val system = ActorSystem("MySystem") val greeter: ActorRef = system.actorOf(Props[GreetingActor]) greeter ! Greeting("London Scala User Group")

Slide 21

Slide 21 text

Reactive Streams Properties of Actors • Message Based / Event Driven • Isolated State • Sane Concurrency Model • Isolated Failure Handling (Supervision) 21

Slide 22

Slide 22 text

Reactive Streams Akka Streams – A Bridge • Converts Publisher/Subscriber API into Actor messages • Simplify creating Publisher/Subscribers using Actors • Attach Reactive streams into existing Akka applications 22

Slide 23

Slide 23 text

Reactive Streams Creating an ActorSubscriber import akka.stream._ class PrintlnActor extends Actor with ActorSubscriber { val requestStrategy = OneByOneRequestStrategy def receive: Receive = { case ActorSubscriberMessage.OnNext(element) => println(element) } } val printlnActor:ActorRef = system.actorOf(Props[PrintlnActor], "println") val subscriber = ActorSubscriber(printlnActor) 23

Slide 24

Slide 24 text

Reactive Streams Creating an ActorPublisher import akka.stream._ class IntActor extends Actor with ActorPublisher[Int] { def receive: Receive = { case ActorPublisherMessage.Request(elements) => while (totalDemand > 0) { onNext(1) } } } val intActor: ActorRef = system.actorOf(Props[IntActor], "intActor") val publisher = ActorPublisher(intActor) 24

Slide 25

Slide 25 text

Reactive Streams Why use Actors as Publishers? • Actors are smart • They can keep internal state to track demand and supply • They can buffer data to meet anticipated demand • Actors are powerful • They can spin up child actors to meet demand • With Akka clustering, can spread load across multiple machines • Actors are resilient • On exception, actor can be killed and restarted by supervisor • Actor interaction is thread-safe, and actor state is private 25

Slide 26

Slide 26 text

Actors Demo

Slide 27

Slide 27 text

Flows

Slide 28

Slide 28 text

Reactive Streams Linear Transformations 28 Source Demand Sink map …

Slide 29

Slide 29 text

Reactive Streams Linear Transformations 29 Source Demand Sink drop map

Slide 30

Slide 30 text

Reactive Streams Linear Stream Transformations • Deterministic (like for collections) • map, filter, collect, grouped, drop, take, groupBy, ... • Time-Based • takeWithin, dropWithin, groupedWithin, ... • Rate-Detached • expand, conflate, buffer, ... • asynchronous • mapAsync, mapAsyncUnordered, ... 30

Slide 31

Slide 31 text

Reactive Streams Non-linear Stream Transformations • Fan-In • merge, concat, zip • Fan-Out • broadcast, route, unzip 31

Slide 32

Slide 32 text

Reactive Streams Fan In 32

Slide 33

Slide 33 text

Reactive Streams Fan Out 33

Slide 34

Slide 34 text

Reactive Streams Materialization • Akka Streams separate the what from the how • declarative Source/Flow/Sink DSL to create blueprint • FlowMaterializer turns this into running Actors • this allows alternative materialization strategies • optimization • verification / validation • cluster deployment • only Akka Actors for now, but more to come! 34

Slide 35

Slide 35 text

FlowGraph Demo

Slide 36

Slide 36 text

Play

Slide 37

Slide 37 text

Reactive Streams Streaming Data • Play can stream data using Iteratees and Enumerators • Streamed data through chunked encoding, using Ok.stream() • But Iteratees and Enumerators are complicated. • And Reactive Streams are simple. 37

Slide 38

Slide 38 text

Reactive Streams Play 2.4 Experimental Features • Reactive Streams Integration! • Adapts Futures, Promises, Enumerators and Iteratees • Note: potential for event loss, no performance tuning • All access through play.api.libs.streams.Streams 38

Slide 39

Slide 39 text

Reactive Streams Streaming video through Play def stream = Action { val headers = Seq(CONTENT_TYPE -> "video/mp4", CACHE_CONTROL -> "no-cache") val framePublisher = video.FFMpeg.readFile(mp4, Akka.system) val frameEnumerator = Streams.publisherToEnumerator(framePublisher) val bytesEnumeratee = Enumeratee.map[Frame](encodeFrame) val chunkedVideoStream = frameEnumerator.through(bytesEnumeratee) Ok.stream(chunkedVideoStream).withHeaders(headers: _*) } 39

Slide 40

Slide 40 text

Play Demo

Slide 41

Slide 41 text

Questions

Slide 42

Slide 42 text

Thanks @markusjura @lutzhuehnken

Slide 43

Slide 43 text

©Typesafe 2014 – All Rights Reserved