SlideShare a Scribd company logo
1 of 69
Download to read offline
Akka streams
Johan Andrén
JEEConf, Kiev, 2018-05-19
Reactive stream processing using
Johan Andrén
Akka Team
Stockholm Scala User Group
@apnylle
johan.andren@lightbend.com
Build powerful reactive, concurrent,
and distributed applications more easily
Akka
Actors – simple & high performance concurrency
Cluster / Remoting, Cluster tools – location transparency,
resilience – and prepackaged tools for building distributed
systems
Streams – back-pressured stream processing
Persistence – CQRS + Event Sourcing for Actors
HTTP – fully async streaming HTTP Server
Complete Java & Scala APIs for all features
What’s in the toolkit?
Reactive Streams
reactive-streams.org
Reactive Streams timeline
Oct 2013
RxJava, Akka and Twitter-
people meeting
“Soon thereafter” 2013
Reactive Streams
Expert group formed
Apr 2015
Reactive Streams Spec 1.0
TCK
5+ impls
2017
Inclusion in JDK9
Akka Streams, RxJava
Vert.x, MongoDB, …
Jul 2015
Akka Streams 1.0
Now/Future
JEP 321: HTTP Client
ADBA - Async JDBC
Jakarta EE?
Reactive Streams
Reactive Streams is an initiative to provide a
standard for asynchronous stream processing with
non-blocking back pressure. This encompasses
efforts aimed at runtime environments (JVM and
JavaScript) as well as network protocols
http://www.reactive-streams.org
“
Reactive Streams
Reactive Streams is an initiative to provide a
standard for asynchronous stream processing with
non-blocking back pressure. This encompasses
efforts aimed at runtime environments (JVM and
JavaScript) as well as network protocols
http://www.reactive-streams.org
“
Stream processing
Source Sink
Flow
Reactive Streams
Reactive Streams is an initiative to provide a
standard for asynchronous stream processing with
non-blocking back pressure. This encompasses
efforts aimed at runtime environments (JVM and
JavaScript) as well as network protocols
http://www.reactive-streams.org
“
Asynchronous stream processing
Source Sink
(possible)
asynchronous
boundaries
Flow
Reactive Streams
Reactive Streams is an initiative to provide a
standard for asynchronous stream processing with
non-blocking back pressure. This encompasses
efforts aimed at runtime environments (JVM and
JavaScript) as well as network protocols
http://www.reactive-streams.org
“
No back pressure
Source Sink
10 msg/s 1 msg/s
Flow
asynchronous
boundary
No back pressure
Source Sink
10 msg/s 1 msg/s
Flow
asynchronous
boundary
OOM!!
No back pressure - bounded buffer
Source Sink
10 msg/s 1 msg/s
Flow
buffer size 6
🗑
asynchronous
boundary
Async non blocking back pressure
Source Sink
1 msg/s
1 msg/s
Flow
buffer size 6
🗑
asynchronous
boundary
Hey! give me 2 more
Reactive Streams
RS Library A RS library B
async
boundary
Reactive Streams
“Make building powerful concurrent &
distributed applications simple.”
Complete and awesome
Java and Scala APIs
(Just like everything in Akka)
Akka Streams
Akka Streams in ~20 seconds:
final ActorSystem system = ActorSystem.create();

final Materializer materializer = ActorMaterializer.create(system);



final Source<Integer, NotUsed> source =

Source.range(0, 20000000);



final Flow<Integer, String, NotUsed> flow =

Flow.fromFunction((Integer n) -> n.toString());



final Sink<String, CompletionStage<Done>> sink =

Sink.foreach(str -> System.out.println(str));



final RunnableGraph<NotUsed> runnable = source.via(flow).to(sink);



runnable.run(materializer);
Akka Streams in ~20 seconds:
final ActorSystem system = ActorSystem.create();

final Materializer materializer = ActorMaterializer.create(system);



final Source<Integer, NotUsed> source =

Source.range(0, 20000000);



final Flow<Integer, String, NotUsed> flow =

Flow.fromFunction((Integer n) -> n.toString());



final Sink<String, CompletionStage<Done>> sink =

Sink.foreach(str -> System.out.println(str));



final RunnableGraph<NotUsed> runnable = source.via(flow).to(sink);



runnable.run(materializer);
Akka Streams in ~20 seconds:
final ActorSystem system = ActorSystem.create();

final Materializer materializer = ActorMaterializer.create(system);



final Source<Integer, NotUsed> source =

Source.range(0, 20000000);



final Flow<Integer, String, NotUsed> flow =

Flow.fromFunction((Integer n) -> n.toString());



final Sink<String, CompletionStage<Done>> sink =

Sink.foreach(str -> System.out.println(str));



final RunnableGraph<NotUsed> runnable = source.via(flow).to(sink);



runnable.run(materializer);
final ActorSystem system = ActorSystem.create();

final Materializer materializer = ActorMaterializer.create(system);



final Source<Integer, NotUsed> source =

Source.range(0, 20000000);



final Flow<Integer, String, NotUsed> flow =

Flow.fromFunction((Integer n) -> n.toString());



final Sink<String, CompletionStage<Done>> sink =

Sink.foreach(str -> System.out.println(str));



final RunnableGraph<NotUsed> runnable = source.via(flow).to(sink);



runnable.run(materializer);
Akka Streams in ~20 seconds:
Source
(range)
Integer
Flow
(fromFunction)
Sink
(foreach)
Integer String String
Akka Streams in ~20 seconds:
implicit val system = ActorSystem()

implicit val mat = ActorMaterializer()



val source = Source(0 to 20000000)



val flow = Flow[Int].map(_.toString())



val sink = Sink.foreach[String](println(_))



val runnable = source.via(flow).to(sink)



runnable.run()
Akka Streams in ~20 seconds:
Source.range(0, 20000000)

.map(Object::toString)

.runForeach(str ->
System.out.println(str), materializer);
Akka Streams in ~20 seconds:
Source(0 to 20000000)

.map(_.toString)

.runForeach(println)
final ActorSystem system = ActorSystem.create();
final Materializer materializer = ActorMaterializer.create(system);
final ConnectHttp host = ConnectHttp.toHost("127.0.0.1", 9000);
final Http http = Http.get(system);
// Note that a more realistic solution would use the EntityStreaming API to stream elements
// as for example JSON Streaming (see the docs for more details)
final Source<ByteString, NotUsed> numbers = Source.range(0, Integer.MAX_VALUE)
.map(n -> ByteString.fromString(n.toString() + "n"));
final Route route =
path("numbers", () ->
get(() ->
complete(HttpResponse.create()
.withStatus(StatusCodes.OK)
.withEntity(HttpEntities.create(
ContentTypes.TEXT_PLAIN_UTF8,
numbers
)))
)
);
final CompletionStage<ServerBinding> bindingCompletionStage =
http.bindAndHandle(route.flow(system, materializer), host, materializer);
bindingCompletionStage.whenComplete((binding, exception) -> {
if (binding != null) {
final InetSocketAddress address = binding.localAddress();
System.out.println("Akka HTTP server running at " + address.getHostString() + ":" + address.getPort());
} else {
System.out.print("Failed to bind HTTP server: " + exception.getMessage());
exception.fillInStackTrace();
}
});
Numbers as a service
final ActorSystem system = ActorSystem.create();
final Materializer materializer = ActorMaterializer.create(system);
final ConnectHttp host = ConnectHttp.toHost("127.0.0.1", 9000);
final Http http = Http.get(system);
// Note that a more realistic solution would use the EntityStreaming API to stream e
// as for example JSON Streaming (see the docs for more details)
final Source<ByteString, NotUsed> numbers = Source.range(0, Integer.MAX_VALUE)
.map(n -> ByteString.fromString(n.toString() + "n"));
final Route route =
path("numbers", () ->
get(() ->
complete(HttpResponse.create()
.withStatus(StatusCodes.OK)
.withEntity(HttpEntities.create(
ContentTypes.TEXT_PLAIN_UTF8,
numbers
)))
)
);
Numbers as a service
final Materializer materializer = ActorMaterializer.create(system);
final ConnectHttp host = ConnectHttp.toHost("127.0.0.1", 9000);
final Http http = Http.get(system);
// Note that a more realistic solution would use the EntityStreaming API to stream e
// as for example JSON Streaming (see the docs for more details)
final Source<ByteString, NotUsed> numbers = Source.range(0, Integer.MAX_VALUE)
.map(n -> ByteString.fromString(n.toString() + "n"));
final Route route =
path("numbers", () ->
get(() ->
complete(HttpResponse.create()
.withStatus(StatusCodes.OK)
.withEntity(HttpEntities.create(
ContentTypes.TEXT_PLAIN_UTF8,
numbers
)))
)
);
final CompletionStage<ServerBinding> bindingCompletionStage =
http.bindAndHandle(route.flow(system, materializer), host, materializer);
bindingCompletionStage.whenComplete((binding, exception) -> {
if (binding != null) {
final InetSocketAddress address = binding.localAddress();
Numbers as a service
complete(HttpResponse.create()
.withStatus(StatusCodes.OK)
.withEntity(HttpEntities.create(
ContentTypes.TEXT_PLAIN_UTF8,
numbers
)))
)
);
final CompletionStage<ServerBinding> bindingCompletionStage =
http.bindAndHandle(route.flow(system, materializer), host, materializer);
bindingCompletionStage.whenComplete((binding, exception) -> {
if (binding != null) {
final InetSocketAddress address = binding.localAddress();
System.out.println("Akka HTTP server running at " + address.getHostString() + ":
address.getPort());
} else {
System.out.print("Failed to bind HTTP server: " + exception.getMessage());
exception.fillInStackTrace();
}
});
Numbers as a service
Numbers as a service
implicit val system = ActorSystem()
import system.dispatcher
implicit val mat = ActorMaterializer()
val numbers = Source(0 to Int.MaxValue).map(n => ByteString(n + "n"))
val route =
path("numbers") {
get {
complete(
HttpResponse(entity = HttpEntity(`text/plain(UTF-8)`, numbers))
)
}
}
val futureBinding = Http().bindAndHandle(route, "127.0.0.1", 8080)
futureBinding.onComplete {
case Success(binding) =>
val address = binding.localAddress
println(s"Akka HTTP server running at ${address.getHostString}:${address.getPort}")
case Failure(ex) =>
println(s"Failed to bind HTTP server: ${ex.getMessage}")
ex.fillInStackTrace()
}
recv buffer
send buffer
🚚
🚚
🚚
🚚
🚚
🚚
🚚
Back pressure over TCP numbers
TCP HTTP
Server
Client
recv buffer
send buffer
🚚
🚚
🚚
🚚
🚚
🚚
🚑
Back pressure over TCP numbers
TCP HTTP
Backpressure
Server
Client
recv buffer
send buffer
🚚
🚚
🚚
🚚
🚚
🚚
🚚
🚚
🚚
🚚
🚑
Back pressure over TCP numbers
TCP HTTP
Backpressure
Backpressure
Server
Client
final ActorSystem system = ActorSystem.create();
final Materializer materializer = ActorMaterializer.create(system);
final Database database = new Database(system);
final ConnectHttp host = ConnectHttp.toHost("127.0.0.1", 8080);
final Http http = Http.get(system);
final Flow<Message, Message, NotUsed> measurementsFlow =
Flow.of(Message.class)
.flatMapConcat((Message message) ->
// handles both strict and streamed ws messages by folding
// the later into a single string (in memory)
message.asTextMessage()
.getStreamedText()
.fold("", (acc, elem) -> acc + elem)
)
.groupedWithin(1000, Duration.of(1, ChronoUnit.SECONDS))
.mapAsync(5, database::asyncBulkInsert)
.map(written ->
TextMessage.create(
"wrote up to: " + written.get(written.size() - 1)
)
);
final Route route = path("measurements", () ->
get(() ->
handleWebSocketMessages(measurementsFlow)
)
);
final CompletionStage<ServerBinding> bindingCompletionStage =
http.bindAndHandle(route.flow(system, materializer), host, materializer);
bindingCompletionStage.whenComplete((binding, exception) -> {
if (binding != null) {
final InetSocketAddress address = binding.localAddress();
System.out.println("Akka HTTP server running at " + address.getHostString() + ":" + address.getPort());
} else {
System.out.print("Failed to bind HTTP server: " + exception.getMessage());
exception.fillInStackTrace();
}
});
A more useful example Credit to: Colin Breck
final Materializer materializer = ActorMaterializer.create(system);
final Database database = new Database(system);
final ConnectHttp host = ConnectHttp.toHost("127.0.0.1", 8080);
final Http http = Http.get(system);
final Flow<Message, Message, NotUsed> measurementsFlow =
Flow.of(Message.class)
.flatMapConcat((Message message) ->
// handles both strict and streamed ws messages by folding
// the later into a single string (in memory)
message.asTextMessage()
.getStreamedText()
.fold("", (acc, elem) -> acc + elem)
)
.groupedWithin(1000, Duration.of(1, ChronoUnit.SECONDS))
.mapAsync(5, database::asyncBulkInsert)
.map(written ->
TextMessage.create(
"wrote up to: " + written.get(written.size() - 1)
)
);
final Route route = path("measurements", () ->
get(() ->
handleWebSocketMessages(measurementsFlow)
)
);
final CompletionStage<ServerBinding> bindingCompletionStage =
A more useful example
final Flow<Message, Message, NotUsed> measurementsFlow =
Flow.of(Message.class)
.flatMapConcat((Message message) ->
// handles both strict and streamed ws messages by folding
// the later into a single string (in memory)
message.asTextMessage()
.getStreamedText()
.fold("", (acc, elem) -> acc + elem)
)
.groupedWithin(1000, Duration.of(1, ChronoUnit.SECONDS))
.mapAsync(5, database::asyncBulkInsert)
.map(written ->
TextMessage.create(
"wrote up to: " + written.get(written.size() - 1)
)
);
final Route route = path("measurements", () ->
get(() ->
handleWebSocketMessages(measurementsFlow)
)
);
final CompletionStage<ServerBinding> bindingCompletionStage =
http.bindAndHandle(route.flow(system, materializer), host, materializer);
bindingCompletionStage.whenComplete((binding, exception) -> {
if (binding != null) {
final InetSocketAddress address = binding.localAddress();
A more useful example
.map(written ->
TextMessage.create(
"wrote up to: " + written.get(written.size() - 1)
)
);
final Route route = path("measurements", () ->
get(() ->
handleWebSocketMessages(measurementsFlow)
)
);
final CompletionStage<ServerBinding> bindingCompletionStage =
http.bindAndHandle(route.flow(system, materializer), host, materializer);
bindingCompletionStage.whenComplete((binding, exception) -> {
if (binding != null) {
final InetSocketAddress address = binding.localAddress();
System.out.println("Akka HTTP server running at " + address.getHostString() + ":"
address.getPort());
} else {
System.out.print("Failed to bind HTTP server: " + exception.getMessage());
exception.fillInStackTrace();
}
});
A more useful example
A more useful example
val measurementsFlow =

Flow[Message].flatMapConcat(message =>

message.asTextMessage.getStreamedText.fold("")(_ + _)

)

.groupedWithin(1000, 1.second)

.mapAsync(5)(Database.asyncBulkInsert)

.map(written => TextMessage("wrote up to: " + written.last))



val route =

path("measurements") {

get {

handleWebSocketMessages(measurementsFlow)

}

}



val futureBinding = Http().bindAndHandle(route, "127.0.0.1", 8080)
The tale of the two pancake chefs
HungrySink
Frying
Pan
BatterSource
Scoops of batter
Pancakes
nom nom nom
asynchronous
boundaries
Roland Patrik
Rolands pipelined pancakes
HungrySinkPan 2BatterSource Pan 1
nom nom nom
Rolands pipelined pancakes
Flow<ScoopOfBatter, HalfCookedPancake, NotUsed> fryingPan1 =

Flow.of(ScoopOfBatter.class).map(batter -> new HalfCookedPancake());



Flow<HalfCookedPancake, Pancake, NotUsed> fryingPan2 =

Flow.of(HalfCookedPancake.class).map(halfCooked -> new Pancake());
Flow<ScoopOfBatter, Pancake, NotUsed> pancakeChef =

fryingPan1.async().via(fryingPan2.async());
section in docs
Rolands pipelined pancakes
// Takes a scoop of batter and creates a pancake with one side cooked
val fryingPan1: Flow[ScoopOfBatter, HalfCookedPancake, NotUsed] =

Flow[ScoopOfBatter].map { batter => HalfCookedPancake() }



// Finishes a half-cooked pancake

val fryingPan2: Flow[HalfCookedPancake, Pancake, NotUsed] =

Flow[HalfCookedPancake].map { halfCooked => Pancake() }


// With the two frying pans we can fully cook pancakes
val pancakeChef: Flow[ScoopOfBatter, Pancake, NotUsed] =

Flow[ScoopOfBatter].via(fryingPan1.async).via(fryingPan2.async)
section in docs
Patriks parallel pancakes
HungrySink
Pan 2
BatterSource
Pan 1
Balance Merge
nom nom nom
Patriks parallel pancakes
Flow<ScoopOfBatter, Pancake, NotUsed> fryingPan =

Flow.of(ScoopOfBatter.class).map(batter -> new Pancake());



Flow<ScoopOfBatter, Pancake, NotUsed> pancakeChef =

Flow.fromGraph(GraphDSL.create(builder -> {

final UniformFanInShape<Pancake, Pancake> mergePancakes =

builder.add(Merge.create(2));

final UniformFanOutShape<ScoopOfBatter, ScoopOfBatter> dispatchBatter =

builder.add(Balance.create(2));



builder.from(dispatchBatter.out(0))
.via(builder.add(fryingPan.async()))
.toInlet(mergePancakes.in(0));

builder.from(dispatchBatter.out(1))
.via(builder.add(fryingPan.async()))
.toInlet(mergePancakes.in(1));



return FlowShape.of(dispatchBatter.in(), mergePancakes.out());

}));
section in docs
Patriks parallel pancakes
val pancakeChef: Flow[ScoopOfBatter, Pancake, NotUsed] =

Flow.fromGraph(GraphDSL.create() { implicit builder =>

import GraphDSL.Implicits._


val dispatchBatter = builder.add(Balance[ScoopOfBatter](2))

val mergePancakes = builder.add(Merge[Pancake](2))



// Using two pipelines, having two frying pans each, in total using

// four frying pans

dispatchBatter.out(0) ~> fryingPan1.async ~> fryingPan2.async ~> mergePancakes.in(0)

dispatchBatter.out(1) ~> fryingPan1.async ~> fryingPan2.async ~> mergePancakes.in(1)



FlowShape(dispatchBatter.in, mergePancakes.out)

})
section in docs
Making pancakes together
HungrySink
Pan 3
BatterSource
Pan 1
Balance Merge
Pan 2
Pan 4
nom nom nom
Built in stages Flow stages
map/fromFunction, mapConcat,
statefulMapConcat, filter, filterNot,
collect, grouped, sliding, scan,
scanAsync, fold, foldAsync, reduce, drop,
take, takeWhile, dropWhile, recover,
recoverWith, recoverWithRetries,
mapError, detach, throttle, intersperse,
limit, limitWeighted, log,
recoverWithRetries, mapAsync,
mapAsyncUnordered, takeWithin,
dropWithin, groupedWithin, initialDelay,
delay, conflate, conflateWithSeed, batch,
batchWeighted, expand, buffer,
prefixAndTail, groupBy, splitWhen,
splitAfter, flatMapConcat, flatMapMerge,
initialTimeout, completionTimeout,
idleTimeout, backpressureTimeout,
keepAlive, initialDelay, merge,
mergeSorted,
Source stages
fromIterator, apply, single, repeat, cycle,
tick, fromFuture, fromCompletionStage,
unfold, unfoldAsync, empty, maybe, failed,
lazily, actorPublisher, actorRef, combine,
unfoldResource, unfoldResourceAsync,
queue, asSubscriber, fromPublisher, zipN,
zipWithN
Sink stages
head, headOption, last, lastOption, ignore,
cancelled, seq, foreach, foreachParallel,
onComplete, lazyInit, queue, fold, reduce,
combine, actorRef, actorRefWithAck,
actorSubscriber, asPublisher,
fromSubscriber
Additional Sink and Source
converters
{from,as}OutputStream,
{from,as}InputStream, {as,from}
javaCollector,
javaCollectorParallelUnordered
File IO Sinks and Sources
fromPath, toPath
mergePreferred, zip, zipWith,
zipWithIndex, concat, prepend,
orElse, interleave, unzip,
unzipWith, broadcast, balance,
partition, watchTermination,
monitor
Even more
Framing, JSON framing, killswitch,
BroadcastHub, MergeHub
But I want to
connect other
things!
A community for Akka Streams connectors
http://github.com/akka/alpakka
Alpakka
Alpakka – a community for Stream connectors
Existing Alpakka
MQTT
AMQP/
RabbitMQ
SSE
Cassandra
FTP/
SFTP
JSON, XML,
CSV, RecordIO
IronMq
Files
AWS
DynamoDB
AWS
SNS,SQS, S3,
Kinesis,Lambda
JMS Azure
Storage Queue
TCP
In Akka
Actors
Reactive
Streams
Java
Streams
Basic
File IO
External
Apache
Geode
Eventuate FS2
Akka Http
HBase
http://developer.lightbend.com/docs/alpakka/current/index.html
and more…
Camel
Kafka
MongoDB
Azure IoT
But my usecase is a
unique snowflake!
❄
❄
❄
GraphStage API
public class Map<A, B> extends GraphStage<FlowShape<A, B>> {
private final Function<A, B> f;
public final Inlet<A> in = Inlet.create("Map.in");
public final Outlet<B> out = Outlet.create("Map.out");
private final FlowShape<A, B> shape = FlowShape.of(in, out);
public Map(Function<A, B> f) {
this.f = f;
}
public FlowShape<A, B> shape() {
return shape;
}
public GraphStageLogic createLogic(Attributes inheritedAttributes) {
return new GraphStageLogic(shape) {
{
setHandler(in, new AbstractInHandler() {
public void onPush() throws Exception {
push(out, f.apply(grab(in)));
}
});
setHandler(out, new AbstractOutHandler() {
public void onPull() throws Exception {
pull(in);
}
});
}
};
}
}
public class Map<A, B> extends GraphStage<FlowShape<A, B>> {
private final Function<A, B> f;
public final Inlet<A> in = Inlet.create("Map.in");
public final Outlet<B> out = Outlet.create("Map.out");
private final FlowShape<A, B> shape = FlowShape.of(in, out);
public Map(Function<A, B> f) {
this.f = f;
}
public FlowShape<A, B> shape() {
return shape;
}
public GraphStageLogic createLogic(Attributes inheritedAttributes) {
return new GraphStageLogic(shape) {
{
setHandler(in, new AbstractInHandler() {
public void onPush() throws Exception {
push(out, f.apply(grab(in)));
}
});
complete sources on github
GraphStage API
public class Map<A, B> extends GraphStage<FlowShape<A, B>> {
private final Function<A, B> f;
public final Inlet<A> in = Inlet.create("Map.in");
public final Outlet<B> out = Outlet.create("Map.out");
private final FlowShape<A, B> shape = FlowShape.of(in, out);
public Map(Function<A, B> f) {
this.f = f;
}
public FlowShape<A, B> shape() {
return shape;
}
public GraphStageLogic createLogic(Attributes inheritedAttributes) {
return new GraphStageLogic(shape) {
{
setHandler(in, new AbstractInHandler() {
public void onPush() throws Exception {
push(out, f.apply(grab(in)));
}
});
complete sources on github
GraphStage API
}
public FlowShape<A, B> shape() {
return shape;
}
public GraphStageLogic createLogic(Attributes inheritedAttributes) {
return new GraphStageLogic(shape) {
{
setHandler(in, new AbstractInHandler() {
public void onPush() throws Exception {
push(out, f.apply(grab(in)));
}
});
setHandler(out, new AbstractOutHandler() {
public void onPull() throws Exception {
pull(in);
}
});
}
};
}
}
complete sources on github
GraphStage API
GraphStage API
class Map[A, B](f: A => B) extends GraphStage[FlowShape[A, B]] {
val in = Inlet[A]("Map.in")
val out = Outlet[B]("Map.out")
val shape = FlowShape.of(in, out)
def createLogic(inheritedAttributes: Attributes): GraphStageLogic =
new GraphStageLogic(shape) {
setHandler(in, new InHandler() {
def onPush(): Unit = {
push(out, f(grab(in)))
}
})
setHandler(out, new AbstractOutHandler() {
def onPull(): Unit = {
pull(in)
}
})
}
}
When to use what abstraction
modelling power
complexity
actors
streams
(completable)
futures
java.concurrency
Actors ❤ Streams = True
Actors – perfect for managing state, things with lifecycles,
restarting, running many separate instances in parallel
A running stream – can be seen as a state, has a lifecycle,
is - not yet started, running, failed, stopped, can be stopped
using special stages
blog.colinbreck.com/integrating-akka-streams-and-akka-actors-part-i/
Again, Colin Breck:
But, distributed systems?
Stream-in-Actor
C-1
Shard C
Akka Streams is a local abstraction
Combine with
Akka Cluster
for distributed superpowers!
Stream-in-Actor
A-1
Shard A
Stream-in-Actor
B-1
Shard B
Stream-in-Actor
B-2
Streams between nodes
Source Flow
Flow Sink
JVM 2
ActorSystem
JVM 1
ActorSystem
(special)
SinkSource Flow
Flow Sink
SourceRef
StreamRefs — new feature since Akka 2.5.10
JVM 2
ActorSystem
JVM 1
ActorSystem
(special)
SinkSource Flow
Flow SinkSourceRef
This end controls
the pace through
backpressure
StreamRefs — new feature since Akka 2.5.10
SourceRef sending side
Scala
class SendingActor extends Actor {
import context.dispatcher
implicit val mat = ActorMaterializer()(context)
val numbersSource = Source(1 to 100000)
def receive = {
case SendMeNumbers ⇒
val ref: Future[SourceRef[Int]] =
numbersSource.runWith(StreamRefs.sourceRef())
val reply: Future[SendMeNumbersReply] =
ref.map(ref => SendMeNumbersReply(ref))
reply pipeTo sender()
}
}
SourceRef receiving side
Scala
class ReceivingActor(sendingActor: ActorRef) extends Actor {
sendingActor ! SendMeNumbers
override def receive: Receive = {
case SendMeNumbersReply(sourceRef) =>
sourceRef.runWith(Sink.foreach(println))
}
}
StreamRefs — new feature since Akka 2.5.10
By design NOT a“distributed automatic stream
processing deployment and management framework”.
(e.g. how Spark, Flink or Beam could be described).
Ideal for
combining Alpakka Enterprise Integration
Data Processing or Ingestion Pipelines between ActorSystems
The community
Forums
discuss.akka.io
Public chat rooms:
http://gitter.im/akka/dev developing Akka
http://gitter.im/akka/akka using Akka
Easy to contribute tickets:
https://github.com/akka/akka/issues?q=is%3Aissue+is%3Aopen+label%3Aeasy-to-contribute
https://github.com/akka/akka/issues?q=is%3Aissue+is%3Aopen+label%3A%22nice-to-have+%28low-prio%29%22
Questions
@apnylle
johan.andren@lightbend.com
http://akka.io
Akka
Thank you!
@apnylle
johan.andren@lightbend.com
All sample code (Java & Scala)
https://github.com/johanandren/akka-stream-samples/tree/jeeconf-2018
http://akka.io
Akka

More Related Content

What's hot

Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Mario Fusco
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOPDzmitry Naskou
 
Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안SANG WON PARK
 
Using ANTLR on real example - convert "string combined" queries into paramete...
Using ANTLR on real example - convert "string combined" queries into paramete...Using ANTLR on real example - convert "string combined" queries into paramete...
Using ANTLR on real example - convert "string combined" queries into paramete...Alexey Diyan
 
Introducing Kafka's Streams API
Introducing Kafka's Streams APIIntroducing Kafka's Streams API
Introducing Kafka's Streams APIconfluent
 
Akka-intro-training-public.pdf
Akka-intro-training-public.pdfAkka-intro-training-public.pdf
Akka-intro-training-public.pdfBernardDeffarges
 
Optimizing Kubernetes Resource Requests/Limits for Cost-Efficiency and Latenc...
Optimizing Kubernetes Resource Requests/Limits for Cost-Efficiency and Latenc...Optimizing Kubernetes Resource Requests/Limits for Cost-Efficiency and Latenc...
Optimizing Kubernetes Resource Requests/Limits for Cost-Efficiency and Latenc...Henning Jacobs
 
Quarkus tips, tricks, and techniques
Quarkus tips, tricks, and techniquesQuarkus tips, tricks, and techniques
Quarkus tips, tricks, and techniquesRed Hat Developers
 
Angular & RXJS: examples and use cases
Angular & RXJS: examples and use casesAngular & RXJS: examples and use cases
Angular & RXJS: examples and use casesFabio Biondi
 
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Michel Schudel
 
CDC Stream Processing with Apache Flink
CDC Stream Processing with Apache FlinkCDC Stream Processing with Apache Flink
CDC Stream Processing with Apache FlinkTimo Walther
 
Real Time UI with Apache Kafka Streaming Analytics of Fast Data and Server Push
Real Time UI with Apache Kafka Streaming Analytics of Fast Data and Server PushReal Time UI with Apache Kafka Streaming Analytics of Fast Data and Server Push
Real Time UI with Apache Kafka Streaming Analytics of Fast Data and Server PushLucas Jellema
 
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project ReactorReactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project ReactorVMware Tanzu
 
Confluent REST Proxy and Schema Registry (Concepts, Architecture, Features)
Confluent REST Proxy and Schema Registry (Concepts, Architecture, Features)Confluent REST Proxy and Schema Registry (Concepts, Architecture, Features)
Confluent REST Proxy and Schema Registry (Concepts, Architecture, Features)Kai Wähner
 
Building an Activity Feed with Cassandra
Building an Activity Feed with CassandraBuilding an Activity Feed with Cassandra
Building an Activity Feed with CassandraMark Dunphy
 
Kafka Tutorial - introduction to the Kafka streaming platform
Kafka Tutorial - introduction to the Kafka streaming platformKafka Tutorial - introduction to the Kafka streaming platform
Kafka Tutorial - introduction to the Kafka streaming platformJean-Paul Azar
 
State transfer With Galera
State transfer With GaleraState transfer With Galera
State transfer With GaleraMydbops
 

What's hot (20)

Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...Reactive Programming for a demanding world: building event-driven and respons...
Reactive Programming for a demanding world: building event-driven and respons...
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 
Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
Apache kafka 모니터링을 위한 Metrics 이해 및 최적화 방안
 
Using ANTLR on real example - convert "string combined" queries into paramete...
Using ANTLR on real example - convert "string combined" queries into paramete...Using ANTLR on real example - convert "string combined" queries into paramete...
Using ANTLR on real example - convert "string combined" queries into paramete...
 
Introducing Kafka's Streams API
Introducing Kafka's Streams APIIntroducing Kafka's Streams API
Introducing Kafka's Streams API
 
Akka-intro-training-public.pdf
Akka-intro-training-public.pdfAkka-intro-training-public.pdf
Akka-intro-training-public.pdf
 
Optimizing Kubernetes Resource Requests/Limits for Cost-Efficiency and Latenc...
Optimizing Kubernetes Resource Requests/Limits for Cost-Efficiency and Latenc...Optimizing Kubernetes Resource Requests/Limits for Cost-Efficiency and Latenc...
Optimizing Kubernetes Resource Requests/Limits for Cost-Efficiency and Latenc...
 
Quarkus tips, tricks, and techniques
Quarkus tips, tricks, and techniquesQuarkus tips, tricks, and techniques
Quarkus tips, tricks, and techniques
 
Kafka basics
Kafka basicsKafka basics
Kafka basics
 
Angular & RXJS: examples and use cases
Angular & RXJS: examples and use casesAngular & RXJS: examples and use cases
Angular & RXJS: examples and use cases
 
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition! Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
Battle Of The Microservice Frameworks: Micronaut versus Quarkus edition!
 
CDC Stream Processing with Apache Flink
CDC Stream Processing with Apache FlinkCDC Stream Processing with Apache Flink
CDC Stream Processing with Apache Flink
 
Introduction to Apache Kafka
Introduction to Apache KafkaIntroduction to Apache Kafka
Introduction to Apache Kafka
 
Real Time UI with Apache Kafka Streaming Analytics of Fast Data and Server Push
Real Time UI with Apache Kafka Streaming Analytics of Fast Data and Server PushReal Time UI with Apache Kafka Streaming Analytics of Fast Data and Server Push
Real Time UI with Apache Kafka Streaming Analytics of Fast Data and Server Push
 
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project ReactorReactive Card Magic: Understanding Spring WebFlux and Project Reactor
Reactive Card Magic: Understanding Spring WebFlux and Project Reactor
 
Confluent REST Proxy and Schema Registry (Concepts, Architecture, Features)
Confluent REST Proxy and Schema Registry (Concepts, Architecture, Features)Confluent REST Proxy and Schema Registry (Concepts, Architecture, Features)
Confluent REST Proxy and Schema Registry (Concepts, Architecture, Features)
 
Database change management with Liquibase
Database change management with LiquibaseDatabase change management with Liquibase
Database change management with Liquibase
 
Building an Activity Feed with Cassandra
Building an Activity Feed with CassandraBuilding an Activity Feed with Cassandra
Building an Activity Feed with Cassandra
 
Kafka Tutorial - introduction to the Kafka streaming platform
Kafka Tutorial - introduction to the Kafka streaming platformKafka Tutorial - introduction to the Kafka streaming platform
Kafka Tutorial - introduction to the Kafka streaming platform
 
State transfer With Galera
State transfer With GaleraState transfer With Galera
State transfer With Galera
 

Similar to Reactive stream processing using Akka streams

Reactive streams processing using Akka Streams
Reactive streams processing using Akka StreamsReactive streams processing using Akka Streams
Reactive streams processing using Akka StreamsJohan Andrén
 
Akka streams - Umeå java usergroup
Akka streams - Umeå java usergroupAkka streams - Umeå java usergroup
Akka streams - Umeå java usergroupJohan Andrén
 
Asynchronous stream processing with Akka Streams
Asynchronous stream processing with Akka StreamsAsynchronous stream processing with Akka Streams
Asynchronous stream processing with Akka StreamsJohan Andrén
 
Streaming all the things with akka streams
Streaming all the things with akka streams   Streaming all the things with akka streams
Streaming all the things with akka streams Johan Andrén
 
Reactive integrations with Akka Streams
Reactive integrations with Akka StreamsReactive integrations with Akka Streams
Reactive integrations with Akka StreamsKonrad Malawski
 
Exploring Reactive Integrations With Akka Streams, Alpakka And Apache Kafka
Exploring Reactive Integrations With Akka Streams, Alpakka And Apache KafkaExploring Reactive Integrations With Akka Streams, Alpakka And Apache Kafka
Exploring Reactive Integrations With Akka Streams, Alpakka And Apache KafkaLightbend
 
VJUG24 - Reactive Integrations with Akka Streams
VJUG24  - Reactive Integrations with Akka StreamsVJUG24  - Reactive Integrations with Akka Streams
VJUG24 - Reactive Integrations with Akka StreamsJohan Andrén
 
Building Stateful Microservices With Akka
Building Stateful Microservices With AkkaBuilding Stateful Microservices With Akka
Building Stateful Microservices With AkkaYaroslav Tkachenko
 
Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Konrad Malawski
 
Reactive Stream Processing with Akka Streams
Reactive Stream Processing with Akka StreamsReactive Stream Processing with Akka Streams
Reactive Stream Processing with Akka StreamsKonrad Malawski
 
Building scalable rest service using Akka HTTP
Building scalable rest service using Akka HTTPBuilding scalable rest service using Akka HTTP
Building scalable rest service using Akka HTTPdatamantra
 
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYCBuilding a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYCKonrad Malawski
 
Reactive Streams 1.0 and Akka Streams
Reactive Streams 1.0 and Akka StreamsReactive Streams 1.0 and Akka Streams
Reactive Streams 1.0 and Akka StreamsDean Wampler
 
Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Ka...
Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Ka...Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Ka...
Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Ka...Reactivesummit
 
Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Kafka
Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & KafkaBack-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Kafka
Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & KafkaAkara Sucharitakul
 
Luis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the wayOleg Podsechin
 
Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...
Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...
Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...Lightbend
 
Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...
Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...
Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...Twilio Inc
 

Similar to Reactive stream processing using Akka streams (20)

Reactive streams processing using Akka Streams
Reactive streams processing using Akka StreamsReactive streams processing using Akka Streams
Reactive streams processing using Akka Streams
 
Akka streams - Umeå java usergroup
Akka streams - Umeå java usergroupAkka streams - Umeå java usergroup
Akka streams - Umeå java usergroup
 
Asynchronous stream processing with Akka Streams
Asynchronous stream processing with Akka StreamsAsynchronous stream processing with Akka Streams
Asynchronous stream processing with Akka Streams
 
Streaming all the things with akka streams
Streaming all the things with akka streams   Streaming all the things with akka streams
Streaming all the things with akka streams
 
Reactive integrations with Akka Streams
Reactive integrations with Akka StreamsReactive integrations with Akka Streams
Reactive integrations with Akka Streams
 
Exploring Reactive Integrations With Akka Streams, Alpakka And Apache Kafka
Exploring Reactive Integrations With Akka Streams, Alpakka And Apache KafkaExploring Reactive Integrations With Akka Streams, Alpakka And Apache Kafka
Exploring Reactive Integrations With Akka Streams, Alpakka And Apache Kafka
 
VJUG24 - Reactive Integrations with Akka Streams
VJUG24  - Reactive Integrations with Akka StreamsVJUG24  - Reactive Integrations with Akka Streams
VJUG24 - Reactive Integrations with Akka Streams
 
Building Stateful Microservices With Akka
Building Stateful Microservices With AkkaBuilding Stateful Microservices With Akka
Building Stateful Microservices With Akka
 
Hot Streaming Java
Hot Streaming JavaHot Streaming Java
Hot Streaming Java
 
Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014Reactive Streams / Akka Streams - GeeCON Prague 2014
Reactive Streams / Akka Streams - GeeCON Prague 2014
 
Reactive Stream Processing with Akka Streams
Reactive Stream Processing with Akka StreamsReactive Stream Processing with Akka Streams
Reactive Stream Processing with Akka Streams
 
Building scalable rest service using Akka HTTP
Building scalable rest service using Akka HTTPBuilding scalable rest service using Akka HTTP
Building scalable rest service using Akka HTTP
 
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYCBuilding a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
 
Reactive Streams 1.0 and Akka Streams
Reactive Streams 1.0 and Akka StreamsReactive Streams 1.0 and Akka Streams
Reactive Streams 1.0 and Akka Streams
 
Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Ka...
Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Ka...Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Ka...
Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Ka...
 
Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Kafka
Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & KafkaBack-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Kafka
Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Kafka
 
Luis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio on RxJS
Luis Atencio on RxJS
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...
Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...
Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...
 
Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...
Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...
Asynchronous Architectures for Implementing Scalable Cloud Services - Evan Co...
 

More from Johan Andrén

Next generation message driven systems with Akka
Next generation message driven systems with AkkaNext generation message driven systems with Akka
Next generation message driven systems with AkkaJohan Andrén
 
Buiilding reactive distributed systems with Akka
Buiilding reactive distributed systems with AkkaBuiilding reactive distributed systems with Akka
Buiilding reactive distributed systems with AkkaJohan Andrén
 
Next generation actors with Akka
Next generation actors with AkkaNext generation actors with Akka
Next generation actors with AkkaJohan Andrén
 
Next generation message driven systems with Akka
Next generation message driven systems with AkkaNext generation message driven systems with Akka
Next generation message driven systems with AkkaJohan Andrén
 
Networks and types - the future of Akka
Networks and types - the future of AkkaNetworks and types - the future of Akka
Networks and types - the future of AkkaJohan Andrén
 
Building reactive distributed systems with Akka
Building reactive distributed systems with Akka Building reactive distributed systems with Akka
Building reactive distributed systems with Akka Johan Andrén
 
Scala usergroup stockholm - reactive integrations with akka streams
Scala usergroup stockholm - reactive integrations with akka streamsScala usergroup stockholm - reactive integrations with akka streams
Scala usergroup stockholm - reactive integrations with akka streamsJohan Andrén
 
Introduction to akka actors with java 8
Introduction to akka actors with java 8Introduction to akka actors with java 8
Introduction to akka actors with java 8Johan Andrén
 
Async - react, don't wait - PingConf
Async - react, don't wait - PingConfAsync - react, don't wait - PingConf
Async - react, don't wait - PingConfJohan Andrén
 
Scala frukostseminarium
Scala frukostseminariumScala frukostseminarium
Scala frukostseminariumJohan Andrén
 
Introduction to Akka
Introduction to AkkaIntroduction to Akka
Introduction to AkkaJohan Andrén
 
Async – react, don't wait
Async – react, don't waitAsync – react, don't wait
Async – react, don't waitJohan Andrén
 
Akka frukostseminarium
Akka   frukostseminariumAkka   frukostseminarium
Akka frukostseminariumJohan Andrén
 
Macros and reflection in scala 2.10
Macros and reflection in scala 2.10Macros and reflection in scala 2.10
Macros and reflection in scala 2.10Johan Andrén
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to ScalaJohan Andrén
 

More from Johan Andrén (16)

Next generation message driven systems with Akka
Next generation message driven systems with AkkaNext generation message driven systems with Akka
Next generation message driven systems with Akka
 
Buiilding reactive distributed systems with Akka
Buiilding reactive distributed systems with AkkaBuiilding reactive distributed systems with Akka
Buiilding reactive distributed systems with Akka
 
Next generation actors with Akka
Next generation actors with AkkaNext generation actors with Akka
Next generation actors with Akka
 
Next generation message driven systems with Akka
Next generation message driven systems with AkkaNext generation message driven systems with Akka
Next generation message driven systems with Akka
 
Networks and types - the future of Akka
Networks and types - the future of AkkaNetworks and types - the future of Akka
Networks and types - the future of Akka
 
Building reactive distributed systems with Akka
Building reactive distributed systems with Akka Building reactive distributed systems with Akka
Building reactive distributed systems with Akka
 
Scala usergroup stockholm - reactive integrations with akka streams
Scala usergroup stockholm - reactive integrations with akka streamsScala usergroup stockholm - reactive integrations with akka streams
Scala usergroup stockholm - reactive integrations with akka streams
 
Introduction to akka actors with java 8
Introduction to akka actors with java 8Introduction to akka actors with java 8
Introduction to akka actors with java 8
 
Async - react, don't wait - PingConf
Async - react, don't wait - PingConfAsync - react, don't wait - PingConf
Async - react, don't wait - PingConf
 
Scala frukostseminarium
Scala frukostseminariumScala frukostseminarium
Scala frukostseminarium
 
Introduction to Akka
Introduction to AkkaIntroduction to Akka
Introduction to Akka
 
Async – react, don't wait
Async – react, don't waitAsync – react, don't wait
Async – react, don't wait
 
Akka frukostseminarium
Akka   frukostseminariumAkka   frukostseminarium
Akka frukostseminarium
 
Macros and reflection in scala 2.10
Macros and reflection in scala 2.10Macros and reflection in scala 2.10
Macros and reflection in scala 2.10
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Duchess scala-2012
Duchess scala-2012Duchess scala-2012
Duchess scala-2012
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native ApplicationsWSO2
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesrafiqahmad00786416
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontologyjohnbeverley2021
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusZilliz
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWERMadyBayot
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...apidays
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Bhuvaneswari Subramani
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...apidays
 

Recently uploaded (20)

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..Understanding the FAA Part 107 License ..
Understanding the FAA Part 107 License ..
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 

Reactive stream processing using Akka streams

  • 1. Akka streams Johan Andrén JEEConf, Kiev, 2018-05-19 Reactive stream processing using
  • 2. Johan Andrén Akka Team Stockholm Scala User Group @apnylle johan.andren@lightbend.com
  • 3. Build powerful reactive, concurrent, and distributed applications more easily Akka
  • 4. Actors – simple & high performance concurrency Cluster / Remoting, Cluster tools – location transparency, resilience – and prepackaged tools for building distributed systems Streams – back-pressured stream processing Persistence – CQRS + Event Sourcing for Actors HTTP – fully async streaming HTTP Server Complete Java & Scala APIs for all features What’s in the toolkit?
  • 6. Reactive Streams timeline Oct 2013 RxJava, Akka and Twitter- people meeting “Soon thereafter” 2013 Reactive Streams Expert group formed Apr 2015 Reactive Streams Spec 1.0 TCK 5+ impls 2017 Inclusion in JDK9 Akka Streams, RxJava Vert.x, MongoDB, … Jul 2015 Akka Streams 1.0 Now/Future JEP 321: HTTP Client ADBA - Async JDBC Jakarta EE?
  • 7. Reactive Streams Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure. This encompasses efforts aimed at runtime environments (JVM and JavaScript) as well as network protocols http://www.reactive-streams.org “
  • 8. Reactive Streams Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure. This encompasses efforts aimed at runtime environments (JVM and JavaScript) as well as network protocols http://www.reactive-streams.org “
  • 10. Reactive Streams Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure. This encompasses efforts aimed at runtime environments (JVM and JavaScript) as well as network protocols http://www.reactive-streams.org “
  • 11. Asynchronous stream processing Source Sink (possible) asynchronous boundaries Flow
  • 12. Reactive Streams Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure. This encompasses efforts aimed at runtime environments (JVM and JavaScript) as well as network protocols http://www.reactive-streams.org “
  • 13. No back pressure Source Sink 10 msg/s 1 msg/s Flow asynchronous boundary
  • 14. No back pressure Source Sink 10 msg/s 1 msg/s Flow asynchronous boundary OOM!!
  • 15. No back pressure - bounded buffer Source Sink 10 msg/s 1 msg/s Flow buffer size 6 🗑 asynchronous boundary
  • 16. Async non blocking back pressure Source Sink 1 msg/s 1 msg/s Flow buffer size 6 🗑 asynchronous boundary Hey! give me 2 more
  • 17. Reactive Streams RS Library A RS library B async boundary
  • 18. Reactive Streams “Make building powerful concurrent & distributed applications simple.”
  • 19. Complete and awesome Java and Scala APIs (Just like everything in Akka) Akka Streams
  • 20. Akka Streams in ~20 seconds: final ActorSystem system = ActorSystem.create();
 final Materializer materializer = ActorMaterializer.create(system);
 
 final Source<Integer, NotUsed> source =
 Source.range(0, 20000000);
 
 final Flow<Integer, String, NotUsed> flow =
 Flow.fromFunction((Integer n) -> n.toString());
 
 final Sink<String, CompletionStage<Done>> sink =
 Sink.foreach(str -> System.out.println(str));
 
 final RunnableGraph<NotUsed> runnable = source.via(flow).to(sink);
 
 runnable.run(materializer);
  • 21. Akka Streams in ~20 seconds: final ActorSystem system = ActorSystem.create();
 final Materializer materializer = ActorMaterializer.create(system);
 
 final Source<Integer, NotUsed> source =
 Source.range(0, 20000000);
 
 final Flow<Integer, String, NotUsed> flow =
 Flow.fromFunction((Integer n) -> n.toString());
 
 final Sink<String, CompletionStage<Done>> sink =
 Sink.foreach(str -> System.out.println(str));
 
 final RunnableGraph<NotUsed> runnable = source.via(flow).to(sink);
 
 runnable.run(materializer);
  • 22. Akka Streams in ~20 seconds: final ActorSystem system = ActorSystem.create();
 final Materializer materializer = ActorMaterializer.create(system);
 
 final Source<Integer, NotUsed> source =
 Source.range(0, 20000000);
 
 final Flow<Integer, String, NotUsed> flow =
 Flow.fromFunction((Integer n) -> n.toString());
 
 final Sink<String, CompletionStage<Done>> sink =
 Sink.foreach(str -> System.out.println(str));
 
 final RunnableGraph<NotUsed> runnable = source.via(flow).to(sink);
 
 runnable.run(materializer);
  • 23. final ActorSystem system = ActorSystem.create();
 final Materializer materializer = ActorMaterializer.create(system);
 
 final Source<Integer, NotUsed> source =
 Source.range(0, 20000000);
 
 final Flow<Integer, String, NotUsed> flow =
 Flow.fromFunction((Integer n) -> n.toString());
 
 final Sink<String, CompletionStage<Done>> sink =
 Sink.foreach(str -> System.out.println(str));
 
 final RunnableGraph<NotUsed> runnable = source.via(flow).to(sink);
 
 runnable.run(materializer); Akka Streams in ~20 seconds: Source (range) Integer Flow (fromFunction) Sink (foreach) Integer String String
  • 24. Akka Streams in ~20 seconds: implicit val system = ActorSystem()
 implicit val mat = ActorMaterializer()
 
 val source = Source(0 to 20000000)
 
 val flow = Flow[Int].map(_.toString())
 
 val sink = Sink.foreach[String](println(_))
 
 val runnable = source.via(flow).to(sink)
 
 runnable.run()
  • 25. Akka Streams in ~20 seconds: Source.range(0, 20000000)
 .map(Object::toString)
 .runForeach(str -> System.out.println(str), materializer);
  • 26. Akka Streams in ~20 seconds: Source(0 to 20000000)
 .map(_.toString)
 .runForeach(println)
  • 27. final ActorSystem system = ActorSystem.create(); final Materializer materializer = ActorMaterializer.create(system); final ConnectHttp host = ConnectHttp.toHost("127.0.0.1", 9000); final Http http = Http.get(system); // Note that a more realistic solution would use the EntityStreaming API to stream elements // as for example JSON Streaming (see the docs for more details) final Source<ByteString, NotUsed> numbers = Source.range(0, Integer.MAX_VALUE) .map(n -> ByteString.fromString(n.toString() + "n")); final Route route = path("numbers", () -> get(() -> complete(HttpResponse.create() .withStatus(StatusCodes.OK) .withEntity(HttpEntities.create( ContentTypes.TEXT_PLAIN_UTF8, numbers ))) ) ); final CompletionStage<ServerBinding> bindingCompletionStage = http.bindAndHandle(route.flow(system, materializer), host, materializer); bindingCompletionStage.whenComplete((binding, exception) -> { if (binding != null) { final InetSocketAddress address = binding.localAddress(); System.out.println("Akka HTTP server running at " + address.getHostString() + ":" + address.getPort()); } else { System.out.print("Failed to bind HTTP server: " + exception.getMessage()); exception.fillInStackTrace(); } }); Numbers as a service
  • 28. final ActorSystem system = ActorSystem.create(); final Materializer materializer = ActorMaterializer.create(system); final ConnectHttp host = ConnectHttp.toHost("127.0.0.1", 9000); final Http http = Http.get(system); // Note that a more realistic solution would use the EntityStreaming API to stream e // as for example JSON Streaming (see the docs for more details) final Source<ByteString, NotUsed> numbers = Source.range(0, Integer.MAX_VALUE) .map(n -> ByteString.fromString(n.toString() + "n")); final Route route = path("numbers", () -> get(() -> complete(HttpResponse.create() .withStatus(StatusCodes.OK) .withEntity(HttpEntities.create( ContentTypes.TEXT_PLAIN_UTF8, numbers ))) ) ); Numbers as a service
  • 29. final Materializer materializer = ActorMaterializer.create(system); final ConnectHttp host = ConnectHttp.toHost("127.0.0.1", 9000); final Http http = Http.get(system); // Note that a more realistic solution would use the EntityStreaming API to stream e // as for example JSON Streaming (see the docs for more details) final Source<ByteString, NotUsed> numbers = Source.range(0, Integer.MAX_VALUE) .map(n -> ByteString.fromString(n.toString() + "n")); final Route route = path("numbers", () -> get(() -> complete(HttpResponse.create() .withStatus(StatusCodes.OK) .withEntity(HttpEntities.create( ContentTypes.TEXT_PLAIN_UTF8, numbers ))) ) ); final CompletionStage<ServerBinding> bindingCompletionStage = http.bindAndHandle(route.flow(system, materializer), host, materializer); bindingCompletionStage.whenComplete((binding, exception) -> { if (binding != null) { final InetSocketAddress address = binding.localAddress(); Numbers as a service
  • 30. complete(HttpResponse.create() .withStatus(StatusCodes.OK) .withEntity(HttpEntities.create( ContentTypes.TEXT_PLAIN_UTF8, numbers ))) ) ); final CompletionStage<ServerBinding> bindingCompletionStage = http.bindAndHandle(route.flow(system, materializer), host, materializer); bindingCompletionStage.whenComplete((binding, exception) -> { if (binding != null) { final InetSocketAddress address = binding.localAddress(); System.out.println("Akka HTTP server running at " + address.getHostString() + ": address.getPort()); } else { System.out.print("Failed to bind HTTP server: " + exception.getMessage()); exception.fillInStackTrace(); } }); Numbers as a service
  • 31. Numbers as a service implicit val system = ActorSystem() import system.dispatcher implicit val mat = ActorMaterializer() val numbers = Source(0 to Int.MaxValue).map(n => ByteString(n + "n")) val route = path("numbers") { get { complete( HttpResponse(entity = HttpEntity(`text/plain(UTF-8)`, numbers)) ) } } val futureBinding = Http().bindAndHandle(route, "127.0.0.1", 8080) futureBinding.onComplete { case Success(binding) => val address = binding.localAddress println(s"Akka HTTP server running at ${address.getHostString}:${address.getPort}") case Failure(ex) => println(s"Failed to bind HTTP server: ${ex.getMessage}") ex.fillInStackTrace() }
  • 32. recv buffer send buffer 🚚 🚚 🚚 🚚 🚚 🚚 🚚 Back pressure over TCP numbers TCP HTTP Server Client
  • 33. recv buffer send buffer 🚚 🚚 🚚 🚚 🚚 🚚 🚑 Back pressure over TCP numbers TCP HTTP Backpressure Server Client
  • 34. recv buffer send buffer 🚚 🚚 🚚 🚚 🚚 🚚 🚚 🚚 🚚 🚚 🚑 Back pressure over TCP numbers TCP HTTP Backpressure Backpressure Server Client
  • 35. final ActorSystem system = ActorSystem.create(); final Materializer materializer = ActorMaterializer.create(system); final Database database = new Database(system); final ConnectHttp host = ConnectHttp.toHost("127.0.0.1", 8080); final Http http = Http.get(system); final Flow<Message, Message, NotUsed> measurementsFlow = Flow.of(Message.class) .flatMapConcat((Message message) -> // handles both strict and streamed ws messages by folding // the later into a single string (in memory) message.asTextMessage() .getStreamedText() .fold("", (acc, elem) -> acc + elem) ) .groupedWithin(1000, Duration.of(1, ChronoUnit.SECONDS)) .mapAsync(5, database::asyncBulkInsert) .map(written -> TextMessage.create( "wrote up to: " + written.get(written.size() - 1) ) ); final Route route = path("measurements", () -> get(() -> handleWebSocketMessages(measurementsFlow) ) ); final CompletionStage<ServerBinding> bindingCompletionStage = http.bindAndHandle(route.flow(system, materializer), host, materializer); bindingCompletionStage.whenComplete((binding, exception) -> { if (binding != null) { final InetSocketAddress address = binding.localAddress(); System.out.println("Akka HTTP server running at " + address.getHostString() + ":" + address.getPort()); } else { System.out.print("Failed to bind HTTP server: " + exception.getMessage()); exception.fillInStackTrace(); } }); A more useful example Credit to: Colin Breck
  • 36. final Materializer materializer = ActorMaterializer.create(system); final Database database = new Database(system); final ConnectHttp host = ConnectHttp.toHost("127.0.0.1", 8080); final Http http = Http.get(system); final Flow<Message, Message, NotUsed> measurementsFlow = Flow.of(Message.class) .flatMapConcat((Message message) -> // handles both strict and streamed ws messages by folding // the later into a single string (in memory) message.asTextMessage() .getStreamedText() .fold("", (acc, elem) -> acc + elem) ) .groupedWithin(1000, Duration.of(1, ChronoUnit.SECONDS)) .mapAsync(5, database::asyncBulkInsert) .map(written -> TextMessage.create( "wrote up to: " + written.get(written.size() - 1) ) ); final Route route = path("measurements", () -> get(() -> handleWebSocketMessages(measurementsFlow) ) ); final CompletionStage<ServerBinding> bindingCompletionStage = A more useful example
  • 37. final Flow<Message, Message, NotUsed> measurementsFlow = Flow.of(Message.class) .flatMapConcat((Message message) -> // handles both strict and streamed ws messages by folding // the later into a single string (in memory) message.asTextMessage() .getStreamedText() .fold("", (acc, elem) -> acc + elem) ) .groupedWithin(1000, Duration.of(1, ChronoUnit.SECONDS)) .mapAsync(5, database::asyncBulkInsert) .map(written -> TextMessage.create( "wrote up to: " + written.get(written.size() - 1) ) ); final Route route = path("measurements", () -> get(() -> handleWebSocketMessages(measurementsFlow) ) ); final CompletionStage<ServerBinding> bindingCompletionStage = http.bindAndHandle(route.flow(system, materializer), host, materializer); bindingCompletionStage.whenComplete((binding, exception) -> { if (binding != null) { final InetSocketAddress address = binding.localAddress(); A more useful example
  • 38. .map(written -> TextMessage.create( "wrote up to: " + written.get(written.size() - 1) ) ); final Route route = path("measurements", () -> get(() -> handleWebSocketMessages(measurementsFlow) ) ); final CompletionStage<ServerBinding> bindingCompletionStage = http.bindAndHandle(route.flow(system, materializer), host, materializer); bindingCompletionStage.whenComplete((binding, exception) -> { if (binding != null) { final InetSocketAddress address = binding.localAddress(); System.out.println("Akka HTTP server running at " + address.getHostString() + ":" address.getPort()); } else { System.out.print("Failed to bind HTTP server: " + exception.getMessage()); exception.fillInStackTrace(); } }); A more useful example
  • 39. A more useful example val measurementsFlow =
 Flow[Message].flatMapConcat(message =>
 message.asTextMessage.getStreamedText.fold("")(_ + _)
 )
 .groupedWithin(1000, 1.second)
 .mapAsync(5)(Database.asyncBulkInsert)
 .map(written => TextMessage("wrote up to: " + written.last))
 
 val route =
 path("measurements") {
 get {
 handleWebSocketMessages(measurementsFlow)
 }
 }
 
 val futureBinding = Http().bindAndHandle(route, "127.0.0.1", 8080)
  • 40. The tale of the two pancake chefs HungrySink Frying Pan BatterSource Scoops of batter Pancakes nom nom nom asynchronous boundaries Roland Patrik
  • 41. Rolands pipelined pancakes HungrySinkPan 2BatterSource Pan 1 nom nom nom
  • 42. Rolands pipelined pancakes Flow<ScoopOfBatter, HalfCookedPancake, NotUsed> fryingPan1 =
 Flow.of(ScoopOfBatter.class).map(batter -> new HalfCookedPancake());
 
 Flow<HalfCookedPancake, Pancake, NotUsed> fryingPan2 =
 Flow.of(HalfCookedPancake.class).map(halfCooked -> new Pancake()); Flow<ScoopOfBatter, Pancake, NotUsed> pancakeChef =
 fryingPan1.async().via(fryingPan2.async()); section in docs
  • 43. Rolands pipelined pancakes // Takes a scoop of batter and creates a pancake with one side cooked val fryingPan1: Flow[ScoopOfBatter, HalfCookedPancake, NotUsed] =
 Flow[ScoopOfBatter].map { batter => HalfCookedPancake() }
 
 // Finishes a half-cooked pancake
 val fryingPan2: Flow[HalfCookedPancake, Pancake, NotUsed] =
 Flow[HalfCookedPancake].map { halfCooked => Pancake() } 
 // With the two frying pans we can fully cook pancakes val pancakeChef: Flow[ScoopOfBatter, Pancake, NotUsed] =
 Flow[ScoopOfBatter].via(fryingPan1.async).via(fryingPan2.async) section in docs
  • 44. Patriks parallel pancakes HungrySink Pan 2 BatterSource Pan 1 Balance Merge nom nom nom
  • 45. Patriks parallel pancakes Flow<ScoopOfBatter, Pancake, NotUsed> fryingPan =
 Flow.of(ScoopOfBatter.class).map(batter -> new Pancake());
 
 Flow<ScoopOfBatter, Pancake, NotUsed> pancakeChef =
 Flow.fromGraph(GraphDSL.create(builder -> {
 final UniformFanInShape<Pancake, Pancake> mergePancakes =
 builder.add(Merge.create(2));
 final UniformFanOutShape<ScoopOfBatter, ScoopOfBatter> dispatchBatter =
 builder.add(Balance.create(2));
 
 builder.from(dispatchBatter.out(0)) .via(builder.add(fryingPan.async())) .toInlet(mergePancakes.in(0));
 builder.from(dispatchBatter.out(1)) .via(builder.add(fryingPan.async())) .toInlet(mergePancakes.in(1));
 
 return FlowShape.of(dispatchBatter.in(), mergePancakes.out());
 })); section in docs
  • 46. Patriks parallel pancakes val pancakeChef: Flow[ScoopOfBatter, Pancake, NotUsed] =
 Flow.fromGraph(GraphDSL.create() { implicit builder =>
 import GraphDSL.Implicits._ 
 val dispatchBatter = builder.add(Balance[ScoopOfBatter](2))
 val mergePancakes = builder.add(Merge[Pancake](2))
 
 // Using two pipelines, having two frying pans each, in total using
 // four frying pans
 dispatchBatter.out(0) ~> fryingPan1.async ~> fryingPan2.async ~> mergePancakes.in(0)
 dispatchBatter.out(1) ~> fryingPan1.async ~> fryingPan2.async ~> mergePancakes.in(1)
 
 FlowShape(dispatchBatter.in, mergePancakes.out)
 }) section in docs
  • 47. Making pancakes together HungrySink Pan 3 BatterSource Pan 1 Balance Merge Pan 2 Pan 4 nom nom nom
  • 48. Built in stages Flow stages map/fromFunction, mapConcat, statefulMapConcat, filter, filterNot, collect, grouped, sliding, scan, scanAsync, fold, foldAsync, reduce, drop, take, takeWhile, dropWhile, recover, recoverWith, recoverWithRetries, mapError, detach, throttle, intersperse, limit, limitWeighted, log, recoverWithRetries, mapAsync, mapAsyncUnordered, takeWithin, dropWithin, groupedWithin, initialDelay, delay, conflate, conflateWithSeed, batch, batchWeighted, expand, buffer, prefixAndTail, groupBy, splitWhen, splitAfter, flatMapConcat, flatMapMerge, initialTimeout, completionTimeout, idleTimeout, backpressureTimeout, keepAlive, initialDelay, merge, mergeSorted, Source stages fromIterator, apply, single, repeat, cycle, tick, fromFuture, fromCompletionStage, unfold, unfoldAsync, empty, maybe, failed, lazily, actorPublisher, actorRef, combine, unfoldResource, unfoldResourceAsync, queue, asSubscriber, fromPublisher, zipN, zipWithN Sink stages head, headOption, last, lastOption, ignore, cancelled, seq, foreach, foreachParallel, onComplete, lazyInit, queue, fold, reduce, combine, actorRef, actorRefWithAck, actorSubscriber, asPublisher, fromSubscriber Additional Sink and Source converters {from,as}OutputStream, {from,as}InputStream, {as,from} javaCollector, javaCollectorParallelUnordered File IO Sinks and Sources fromPath, toPath mergePreferred, zip, zipWith, zipWithIndex, concat, prepend, orElse, interleave, unzip, unzipWith, broadcast, balance, partition, watchTermination, monitor Even more Framing, JSON framing, killswitch, BroadcastHub, MergeHub
  • 49. But I want to connect other things!
  • 50. A community for Akka Streams connectors http://github.com/akka/alpakka Alpakka
  • 51. Alpakka – a community for Stream connectors Existing Alpakka MQTT AMQP/ RabbitMQ SSE Cassandra FTP/ SFTP JSON, XML, CSV, RecordIO IronMq Files AWS DynamoDB AWS SNS,SQS, S3, Kinesis,Lambda JMS Azure Storage Queue TCP In Akka Actors Reactive Streams Java Streams Basic File IO External Apache Geode Eventuate FS2 Akka Http HBase http://developer.lightbend.com/docs/alpakka/current/index.html and more… Camel Kafka MongoDB Azure IoT
  • 52. But my usecase is a unique snowflake! ❄ ❄ ❄
  • 53. GraphStage API public class Map<A, B> extends GraphStage<FlowShape<A, B>> { private final Function<A, B> f; public final Inlet<A> in = Inlet.create("Map.in"); public final Outlet<B> out = Outlet.create("Map.out"); private final FlowShape<A, B> shape = FlowShape.of(in, out); public Map(Function<A, B> f) { this.f = f; } public FlowShape<A, B> shape() { return shape; } public GraphStageLogic createLogic(Attributes inheritedAttributes) { return new GraphStageLogic(shape) { { setHandler(in, new AbstractInHandler() { public void onPush() throws Exception { push(out, f.apply(grab(in))); } }); setHandler(out, new AbstractOutHandler() { public void onPull() throws Exception { pull(in); } }); } }; } }
  • 54. public class Map<A, B> extends GraphStage<FlowShape<A, B>> { private final Function<A, B> f; public final Inlet<A> in = Inlet.create("Map.in"); public final Outlet<B> out = Outlet.create("Map.out"); private final FlowShape<A, B> shape = FlowShape.of(in, out); public Map(Function<A, B> f) { this.f = f; } public FlowShape<A, B> shape() { return shape; } public GraphStageLogic createLogic(Attributes inheritedAttributes) { return new GraphStageLogic(shape) { { setHandler(in, new AbstractInHandler() { public void onPush() throws Exception { push(out, f.apply(grab(in))); } }); complete sources on github GraphStage API
  • 55. public class Map<A, B> extends GraphStage<FlowShape<A, B>> { private final Function<A, B> f; public final Inlet<A> in = Inlet.create("Map.in"); public final Outlet<B> out = Outlet.create("Map.out"); private final FlowShape<A, B> shape = FlowShape.of(in, out); public Map(Function<A, B> f) { this.f = f; } public FlowShape<A, B> shape() { return shape; } public GraphStageLogic createLogic(Attributes inheritedAttributes) { return new GraphStageLogic(shape) { { setHandler(in, new AbstractInHandler() { public void onPush() throws Exception { push(out, f.apply(grab(in))); } }); complete sources on github GraphStage API
  • 56. } public FlowShape<A, B> shape() { return shape; } public GraphStageLogic createLogic(Attributes inheritedAttributes) { return new GraphStageLogic(shape) { { setHandler(in, new AbstractInHandler() { public void onPush() throws Exception { push(out, f.apply(grab(in))); } }); setHandler(out, new AbstractOutHandler() { public void onPull() throws Exception { pull(in); } }); } }; } } complete sources on github GraphStage API
  • 57. GraphStage API class Map[A, B](f: A => B) extends GraphStage[FlowShape[A, B]] { val in = Inlet[A]("Map.in") val out = Outlet[B]("Map.out") val shape = FlowShape.of(in, out) def createLogic(inheritedAttributes: Attributes): GraphStageLogic = new GraphStageLogic(shape) { setHandler(in, new InHandler() { def onPush(): Unit = { push(out, f(grab(in))) } }) setHandler(out, new AbstractOutHandler() { def onPull(): Unit = { pull(in) } }) } }
  • 58. When to use what abstraction modelling power complexity actors streams (completable) futures java.concurrency
  • 59. Actors ❤ Streams = True Actors – perfect for managing state, things with lifecycles, restarting, running many separate instances in parallel A running stream – can be seen as a state, has a lifecycle, is - not yet started, running, failed, stopped, can be stopped using special stages blog.colinbreck.com/integrating-akka-streams-and-akka-actors-part-i/ Again, Colin Breck:
  • 60. But, distributed systems? Stream-in-Actor C-1 Shard C Akka Streams is a local abstraction Combine with Akka Cluster for distributed superpowers! Stream-in-Actor A-1 Shard A Stream-in-Actor B-1 Shard B Stream-in-Actor B-2
  • 62. JVM 2 ActorSystem JVM 1 ActorSystem (special) SinkSource Flow Flow Sink SourceRef StreamRefs — new feature since Akka 2.5.10
  • 63. JVM 2 ActorSystem JVM 1 ActorSystem (special) SinkSource Flow Flow SinkSourceRef This end controls the pace through backpressure StreamRefs — new feature since Akka 2.5.10
  • 64. SourceRef sending side Scala class SendingActor extends Actor { import context.dispatcher implicit val mat = ActorMaterializer()(context) val numbersSource = Source(1 to 100000) def receive = { case SendMeNumbers ⇒ val ref: Future[SourceRef[Int]] = numbersSource.runWith(StreamRefs.sourceRef()) val reply: Future[SendMeNumbersReply] = ref.map(ref => SendMeNumbersReply(ref)) reply pipeTo sender() } }
  • 65. SourceRef receiving side Scala class ReceivingActor(sendingActor: ActorRef) extends Actor { sendingActor ! SendMeNumbers override def receive: Receive = { case SendMeNumbersReply(sourceRef) => sourceRef.runWith(Sink.foreach(println)) } }
  • 66. StreamRefs — new feature since Akka 2.5.10 By design NOT a“distributed automatic stream processing deployment and management framework”. (e.g. how Spark, Flink or Beam could be described). Ideal for combining Alpakka Enterprise Integration Data Processing or Ingestion Pipelines between ActorSystems
  • 67. The community Forums discuss.akka.io Public chat rooms: http://gitter.im/akka/dev developing Akka http://gitter.im/akka/akka using Akka Easy to contribute tickets: https://github.com/akka/akka/issues?q=is%3Aissue+is%3Aopen+label%3Aeasy-to-contribute https://github.com/akka/akka/issues?q=is%3Aissue+is%3Aopen+label%3A%22nice-to-have+%28low-prio%29%22
  • 69. Thank you! @apnylle johan.andren@lightbend.com All sample code (Java & Scala) https://github.com/johanandren/akka-stream-samples/tree/jeeconf-2018 http://akka.io Akka