9. Streams
Real 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
19. Reactive Streams - Inter-op
http://reactive-streams.org
We want to make different implementations
co-operate with each other.
20. Reactive Streams - Inter-op
http://reactive-streams.org
The different implementations “talk to each other”
using the Reactive Streams protocol.
21. 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.
24. import akka.stream.FlowMaterializer
import ratpack.http.ResponseChunks
import java.util.function.Consumer
import ratpack.test.http.TestHttpClient
import reactor.rx.Streams
object ScalaMain extends App {
val system = ActorSystem("InteropTest")
implicit val mat =
FlowMaterializer()(system)
RxRatpack.initialize()
val handler = new Handler {
override def handle(ctx: Context): Unit ={
// RxJava Observable
val intObs =
Observable.from((1 to 10).asJava)
25. import akka.stream.FlowMaterializer
import ratpack.http.ResponseChunks
import java.util.function.Consumer
import ratpack.test.http.TestHttpClient
import reactor.rx.Streams
object ScalaMain extends App {
val system = ActorSystem("InteropTest")
implicit val mat =
FlowMaterializer()(system)
RxRatpack.initialize()
val handler = new Handler {
override def handle(ctx: Context): Unit ={
// RxJava Observable
val intObs =
Observable.from((1 to 10).asJava)
26. import akka.stream.FlowMaterializer
import ratpack.http.ResponseChunks
import java.util.function.Consumer
import ratpack.test.http.TestHttpClient
import reactor.rx.Streams
object ScalaMain extends App {
val system = ActorSystem("InteropTest")
implicit val mat =
FlowMaterializer()(system)
RxRatpack.initialize()
val handler = new Handler {
override def handle(ctx: Context): Unit ={
// RxJava Observable
val intObs =
Observable.from((1 to 10).asJava)
27. RxRatpack.initialize()
val handler = new Handler {
override def handle(ctx: Context): Unit ={
// RxJava Observable
val intObs =
Observable.from((1 to 10).asJava)
// Reactive Streams Publisher
val intPub =
RxReactiveStreams.toPublisher(intObs)
// Akka Streams Source
val stringSource =
Source(intPub).map(_.toString)
// Reactive Streams Publisher
val stringPub =
stringSource.runWith(
Sink.fanoutPublisher(1, 1))
28. // Reactive Streams Publisher
val intPub =
RxReactiveStreams.toPublisher(intObs)
// Akka Streams Source
val stringSource =
Source(intPub).map(_.toString)
// Reactive Streams Publisher
val stringPub =
stringSource.runWith(
Sink.fanoutPublisher(1, 1))
// Reactor Stream
val reactor.function.Function
val linesStream =
Streams.create(stringPub).map[String](
new Function[String, String] {
override def apply(in: String) = in+"n"
})
29. val stringPub =
stringSource.runWith(
Sink.fanoutPublisher(1, 1))
// Reactor Stream
val reactor.function.Function
val linesStream =
Streams.create(stringPub).map[String](
new Function[String, String] {
override def apply(in: String) = in+"n"
})
// and now render the HTTP response
ctx.render(
ResponseChunks.stringChunks(linesStream))
}
})
EmbeddedApp.fromHandler(handler).test(
30. // and now render the HTTP response
ctx.render(
ResponseChunks.stringChunks(linesStream))
}
})
EmbeddedApp.fromHandler(handler).test(
new Consumer[TestHttpClient] {
override def accept(
client: TestHttpClient): Unit = {
val text = client.getText()
println(text)
system.shutdown()
}
})
}
31. // and now render the HTTP response
ctx.render(
ResponseChunks.stringChunks(linesStream))
}
})
EmbeddedApp.fromHandler(handler).test(
new Consumer[TestHttpClient] {
override def accept(
client: TestHttpClient): Unit = {
val text = client.getText()
println(text)
system.shutdown()
}
})
}
32. Reactive Streams - Inter-op
public interface Subscriber<T> {
public void onSubscribe(Subscription s);
public void onNext(T t);
public void onError(Throwable t);
public void onComplete();
}
public interface Publisher<T> {
public void subscribe(Subscriber<? super T> s);
}
public interface Subscription {
public void request(long n);
public void cancel();
}
63. Akka
• Fault tolerant
• Supervision hierarchies
• Failure detection
• Asynchronous data processing
• Optimised for high performance
• both in-jvm and across network
• Adaptive Cluster
• Load balancing among Cluster Nodes
Actor 131 Actor 132
Supervisor 1
Actor 12 Actor 13
Actor 111 Actor 112
Supervisor 11
65. Akka
Akka is a high-performance concurrency
library for Scala and Java.
At it’s core it focuses on the Actor Model:
66. An Actor can only:
• Send and receive messages
• Create Actors
• Change it’s behaviour
Akka
Akka is a high-performance concurrency
library for Scala and Java.
At it’s core it focuses on the Actor Model:
67. class Player extends Actor {
def receive = {
case NextTurn => sender() ! decideOnMove()
}
def decideOnMove(): Move = ???
}
Akka Actors
73. Akka Streams – Linear Flow
Flow[Double].map(_.toInt). [...]
No Source attached yet.
“Pipe ready to work with Doubles”.
74. Akka Streams – Linear Flow
implicit val sys = ActorSystem()
implicit val mat = ActorMaterializer()
Source(1 to 3).runWith(Sink.foreach(println))
75. Akka Streams – Linear Flow
Source(1 to 3).runWith(Sink.foreach(println))
// sugar for runWith
Source(1 to 3).foreach(println)
implicit val sys = ActorSystem()
implicit val mat = ActorMaterializer()
76. Akka Streams – Linear Flow
Source(1 to 3).runWith(Sink.foreach(println))
// sugar for runWith
Source(1 to 3).foreach(println)
Sink.fold
Sink.head
Sink.ignore
Sink.publisher
Sink.cancelled
// your own Sink
…
implicit val sys = ActorSystem()
implicit val mat = ActorMaterializer()
77. Akka Streams – Flows are reusable
sink.runWith(Source(1 to 10))
sink.runWith(Source(1 to 100))
sink.runWith(Source(1 to 1000))
source.runWith(Sink.ignore)
source.runWith(Sink.foreach(println))
Multiple materializations
val ready = source.to(Sink.ignore)
ready.run()
ready.run()
78. Akka Streams <-> Actors – Advanced
val subscriber = ActorSubscriber(
system.actorOf(Props[SubStreamParent], ”parent”)
)
Source(1 to 100)
.map(_.toString)
.filter(_.length == 2)
.drop(2)
.conflate(seed => seed)((acc, i) => acc + i)
.groupBy(_.last)
.runWith(subscriber)
All the usual ops available for Linear Flows.