SlideShare a Scribd company logo
Akka streams
Johan Andrén
Umeå Java Usergroup, 2017-06-13
Johan Andrén
Akka Team
Stockholm Scala User Group
@apnylle
johan.andren@lightbend.com
Make building powerful concurrent &
distributed applications simple.
Akka is a toolkit and runtime
for building highly concurrent,
distributed, and resilient
message-driven applications
on the JVM
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 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
??? 2015
JEP-266
inclusion in JDK9
Akka Streams, RxJava
Vert.x, MongoDB, …
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.”
When to use what abstraction
modelling power
complexity
actors
streams
futures/cs
java.concurrency
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);
complete sources on github
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);
complete sources on github
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:
complete sources on github
Source String Flow SinkString Integer Integer
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()
complete sources on github
Akka Streams in ~20 seconds:
Source.range(0, 20000000)

.map(Object::toString)

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

.map(_.toString)

.runForeach(println)
complete sources on github
Numbers as a service
final Source<ByteString, NotUsed> numbers = Source.unfold(0L, n -> {

long next = n + 1;

return Optional.of(Pair.create(next, next));

}).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);
complete sources on github
final Source<ByteString, NotUsed> numbers = Source.unfold(0L, n -> {

long next = n + 1;

return Optional.of(Pair.create(next, next));

}).map(n -> ByteString.fromString(n.toString() + "n"));





final Route route =

path("numbers", () ->

get(() ->

complete(HttpResponse.create()

.withStatus(StatusCodes.OK)

.withEntity(HttpEntities.create(

Numbers as a service
complete sources on github
return Optional.of(Pair.create(next, next));

}).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);
Numbers as a service
complete sources on github
Numbers as a service
val numbers =

Source.unfold(0L) { (n) =>

val next = n + 1

Some((next, next))

}.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)
complete sources on github
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
A more useful example
complete sources on github
final Flow<Message, Message, NotUsed> measurementsFlow =

Flow.of(Message.class)

.flatMapConcat((Message message) ->

message.asTextMessage()

.getStreamedText()

.fold("", (acc, elem) -> acc + elem)

)

.groupedWithin(1000, FiniteDuration.create(1, 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);
Credit to: Colin Breck
final Flow<Message, Message, NotUsed> measurementsFlow =

Flow.of(Message.class)

.flatMapConcat((Message message) ->

message.asTextMessage()

.getStreamedText()

.fold("", (acc, elem) -> acc + elem)

)

.groupedWithin(1000, FiniteDuration.create(1, SECONDS))

.mapAsync(5, database::asyncBulkInsert)

.map(written ->

TextMessage.create("wrote up to: " +
written.get(written.size() - 1))

);



final Route route = path("measurements", () ->

A more useful example
complete sources on github
Credit to: Colin Breck
)

.groupedWithin(1000, FiniteDuration.create(1, 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);
A more useful example
complete sources on github
Credit to: Colin Breck
A more useful example
complete sources on github
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
XML,CVS
IronMq
Files
AWS
DynamoDB
AWS
SNS,SQS, S3,
Lambda
JMS CSV
TCP
In Akka
Actors
Reactive
Streams
Java
Streams
Basic
File IO
External
geode
Azure
Eventuate
FS2
Akka Http
HBase
http://developer.lightbend.com/docs/alpakka/current/index.html
Google Cloud
Pub/Sub
Camel
Kafka
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() {

@Override

public void onPush() throws Exception {

push(out, f.apply(grab(in)));

}

});

setHandler(out, new AbstractOutHandler() {

@Override

public void onPull() throws Exception {

pull(in);

}

});

}

};

}

}
complete sources on github
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() {

@Override

public void onPush() throws Exception {

GraphStage API
complete sources on github
public FlowShape<A,B> shape() {

return shape;

}

public GraphStageLogic createLogic(Attributes inheritedAttributes) {

return new GraphStageLogic(shape) {

{

setHandler(in, new AbstractInHandler() {

@Override

public void onPush() throws Exception {

push(out, f.apply(grab(in)));

}

});

setHandler(out, new AbstractOutHandler() {

@Override

public void onPull() throws Exception {

pull(in);

}

});

}

};

}

}
GraphStage API
complete sources on github
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")

override val shape = FlowShape.of(in, out)



override def createLogic(attr: Attributes): GraphStageLogic =

new GraphStageLogic(shape) {

setHandler(in, new InHandler {

override def onPush(): Unit = {

push(out, f(grab(in)))

}

})

setHandler(out, new OutHandler {

override def onPull(): Unit = {

pull(in)

}

})

}

}
complete sources on github
The community
Mailing list:
https://groups.google.com/group/akka-user
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
~200 active contributors!
Frågor?
@apnylle
johan.andren@lightbend.com
http://akka.io
Akka
Tack för att ni lyssnade!
@apnylle
johan.andren@lightbend.com
github.com/johanandren
All exempelkod (Java & Scala)
https://github.com/johanandren/akka-stream-samples/tree/ume-jug
http://akka.io
Akka

More Related Content

What's hot (20)

PDF
Buiilding reactive distributed systems with Akka
Johan Andrén
 
PDF
Reactive Streams / Akka Streams - GeeCON Prague 2014
Konrad Malawski
 
PDF
Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...
Lightbend
 
PDF
A dive into akka streams: from the basics to a real-world scenario
Gioia Ballin
 
PDF
VJUG24 - Reactive Integrations with Akka Streams
Johan Andrén
 
PDF
Using akka streams to access s3 objects
Mikhail Girkin
 
PDF
Akka streams
mircodotta
 
PDF
Next generation message driven systems with Akka
Johan Andrén
 
PDF
Akka Streams and HTTP
Roland Kuhn
 
PDF
HBase RowKey design for Akka Persistence
Konrad Malawski
 
PDF
Journey into Reactive Streams and Akka Streams
Kevin Webber
 
PPTX
Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Ka...
Reactivesummit
 
PDF
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Konrad Malawski
 
PDF
Reactive Stream Processing with Akka Streams
Konrad Malawski
 
PDF
2014 akka-streams-tokyo-japanese
Konrad Malawski
 
PDF
[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)
Konrad Malawski
 
PDF
Reactive programming on Android
Tomáš Kypta
 
PDF
Next generation message driven systems with Akka
Johan Andrén
 
PDF
Reactive Streams: Handling Data-Flow the Reactive Way
Roland Kuhn
 
PDF
Networks and types - the future of Akka
Johan Andrén
 
Buiilding reactive distributed systems with Akka
Johan Andrén
 
Reactive Streams / Akka Streams - GeeCON Prague 2014
Konrad Malawski
 
Build Real-Time Streaming ETL Pipelines With Akka Streams, Alpakka And Apache...
Lightbend
 
A dive into akka streams: from the basics to a real-world scenario
Gioia Ballin
 
VJUG24 - Reactive Integrations with Akka Streams
Johan Andrén
 
Using akka streams to access s3 objects
Mikhail Girkin
 
Akka streams
mircodotta
 
Next generation message driven systems with Akka
Johan Andrén
 
Akka Streams and HTTP
Roland Kuhn
 
HBase RowKey design for Akka Persistence
Konrad Malawski
 
Journey into Reactive Streams and Akka Streams
Kevin Webber
 
Back-Pressure in Action: Handling High-Burst Workloads with Akka Streams & Ka...
Reactivesummit
 
Fresh from the Oven (04.2015): Experimental Akka Typed and Akka Streams
Konrad Malawski
 
Reactive Stream Processing with Akka Streams
Konrad Malawski
 
2014 akka-streams-tokyo-japanese
Konrad Malawski
 
[Tokyo Scala User Group] Akka Streams & Reactive Streams (0.7)
Konrad Malawski
 
Reactive programming on Android
Tomáš Kypta
 
Next generation message driven systems with Akka
Johan Andrén
 
Reactive Streams: Handling Data-Flow the Reactive Way
Roland Kuhn
 
Networks and types - the future of Akka
Johan Andrén
 

Similar to Akka streams - Umeå java usergroup (20)

PDF
Exploring Reactive Integrations With Akka Streams, Alpakka And Apache Kafka
Lightbend
 
PDF
Reactive integrations with Akka Streams
Konrad Malawski
 
PPTX
Reactive Streams - László van den Hoek
RubiX BV
 
PDF
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Konrad Malawski
 
PPTX
Intro to Akka Streams
Michael Kendra
 
PDF
Akka stream and Akka CQRS
Milan Das
 
PDF
Akka A to Z: A Guide To The Industry’s Best Toolkit for Fast Data and Microse...
Lightbend
 
PDF
Akka in Action 1st Edition Raymond Roestenburg download pdf
himlalnunys
 
PDF
[PDF Download] Akka in Action 1st Edition Raymond Roestenburg fulll chapter
labliinagai
 
PDF
Understanding Akka Streams, Back Pressure, and Asynchronous Architectures
Lightbend
 
PDF
Functional Programming and Composing Actors
legendofklang
 
ODP
Introduction to Akka Streams [Part-I]
Knoldus Inc.
 
PDF
Akka Revealed: A JVM Architect's Journey From Resilient Actors To Scalable Cl...
Lightbend
 
PDF
Reactive Streams 1.0 and Akka Streams
Dean Wampler
 
PDF
Not Only Streams for Akademia JLabs
Konrad Malawski
 
PDF
Writing Asynchronous Programs with Scala & Akka
Yardena Meymann
 
PPTX
Taking Akka Streams & Akka Http to Large Scale Production Applications
Akara Sucharitakul
 
PDF
Akka Streams - From Zero to Kafka
Mark Harrison
 
PDF
PSUG #52 Dataflow and simplified reactive programming with Akka-streams
Stephane Manciot
 
PPTX
Lessons Learned From PayPal: Implementing Back-Pressure With Akka Streams And...
Lightbend
 
Exploring Reactive Integrations With Akka Streams, Alpakka And Apache Kafka
Lightbend
 
Reactive integrations with Akka Streams
Konrad Malawski
 
Reactive Streams - László van den Hoek
RubiX BV
 
Building a Reactive System with Akka - Workshop @ O'Reilly SAConf NYC
Konrad Malawski
 
Intro to Akka Streams
Michael Kendra
 
Akka stream and Akka CQRS
Milan Das
 
Akka A to Z: A Guide To The Industry’s Best Toolkit for Fast Data and Microse...
Lightbend
 
Akka in Action 1st Edition Raymond Roestenburg download pdf
himlalnunys
 
[PDF Download] Akka in Action 1st Edition Raymond Roestenburg fulll chapter
labliinagai
 
Understanding Akka Streams, Back Pressure, and Asynchronous Architectures
Lightbend
 
Functional Programming and Composing Actors
legendofklang
 
Introduction to Akka Streams [Part-I]
Knoldus Inc.
 
Akka Revealed: A JVM Architect's Journey From Resilient Actors To Scalable Cl...
Lightbend
 
Reactive Streams 1.0 and Akka Streams
Dean Wampler
 
Not Only Streams for Akademia JLabs
Konrad Malawski
 
Writing Asynchronous Programs with Scala & Akka
Yardena Meymann
 
Taking Akka Streams & Akka Http to Large Scale Production Applications
Akara Sucharitakul
 
Akka Streams - From Zero to Kafka
Mark Harrison
 
PSUG #52 Dataflow and simplified reactive programming with Akka-streams
Stephane Manciot
 
Lessons Learned From PayPal: Implementing Back-Pressure With Akka Streams And...
Lightbend
 
Ad

More from Johan Andrén (9)

PDF
Building reactive distributed systems with Akka
Johan Andrén
 
PDF
Introduction to akka actors with java 8
Johan Andrén
 
PDF
Scala frukostseminarium
Johan Andrén
 
PDF
Introduction to Akka
Johan Andrén
 
PDF
Async – react, don't wait
Johan Andrén
 
PDF
Akka frukostseminarium
Johan Andrén
 
PDF
Macros and reflection in scala 2.10
Johan Andrén
 
PDF
Introduction to Scala
Johan Andrén
 
PDF
Duchess scala-2012
Johan Andrén
 
Building reactive distributed systems with Akka
Johan Andrén
 
Introduction to akka actors with java 8
Johan Andrén
 
Scala frukostseminarium
Johan Andrén
 
Introduction to Akka
Johan Andrén
 
Async – react, don't wait
Johan Andrén
 
Akka frukostseminarium
Johan Andrén
 
Macros and reflection in scala 2.10
Johan Andrén
 
Introduction to Scala
Johan Andrén
 
Duchess scala-2012
Johan Andrén
 
Ad

Recently uploaded (20)

PPTX
Smart Factory Monitoring IIoT in Machine and Production Operations.pptx
Rejig Digital
 
PDF
TrustArc Webinar - Navigating APAC Data Privacy Laws: Compliance & Challenges
TrustArc
 
PDF
Bitkom eIDAS Summit | European Business Wallet: Use Cases, Macroeconomics, an...
Carsten Stoecker
 
PDF
Why aren't you using FME Flow's CPU Time?
Safe Software
 
PDF
Hyderabad MuleSoft In-Person Meetup (June 21, 2025) Slides
Ravi Tamada
 
PDF
''Taming Explosive Growth: Building Resilience in a Hyper-Scaled Financial Pl...
Fwdays
 
PPTX
Enabling the Digital Artisan – keynote at ICOCI 2025
Alan Dix
 
PDF
How to Comply With Saudi Arabia’s National Cybersecurity Regulations.pdf
Bluechip Advanced Technologies
 
PPTX
Reimaginando la Ciberdefensa: De Copilots a Redes de Agentes
Cristian Garcia G.
 
PDF
My Journey from CAD to BIM: A True Underdog Story
Safe Software
 
PDF
🚀 Let’s Build Our First Slack Workflow! 🔧.pdf
SanjeetMishra29
 
PDF
Enhancing Environmental Monitoring with Real-Time Data Integration: Leveragin...
Safe Software
 
PDF
Pipeline Industry IoT - Real Time Data Monitoring
Safe Software
 
PDF
Unlocking FME Flow’s Potential: Architecture Design for Modern Enterprises
Safe Software
 
PPTX
Smarter Governance with AI: What Every Board Needs to Know
OnBoard
 
PDF
Optimizing the trajectory of a wheel loader working in short loading cycles
Reno Filla
 
PDF
Dev Dives: Accelerating agentic automation with Autopilot for Everyone
UiPathCommunity
 
PDF
99 Bottles of Trust on the Wall — Operational Principles for Trust in Cyber C...
treyka
 
PDF
Hello I'm "AI" Your New _________________
Dr. Tathagat Varma
 
PDF
5 Things to Consider When Deploying AI in Your Enterprise
Safe Software
 
Smart Factory Monitoring IIoT in Machine and Production Operations.pptx
Rejig Digital
 
TrustArc Webinar - Navigating APAC Data Privacy Laws: Compliance & Challenges
TrustArc
 
Bitkom eIDAS Summit | European Business Wallet: Use Cases, Macroeconomics, an...
Carsten Stoecker
 
Why aren't you using FME Flow's CPU Time?
Safe Software
 
Hyderabad MuleSoft In-Person Meetup (June 21, 2025) Slides
Ravi Tamada
 
''Taming Explosive Growth: Building Resilience in a Hyper-Scaled Financial Pl...
Fwdays
 
Enabling the Digital Artisan – keynote at ICOCI 2025
Alan Dix
 
How to Comply With Saudi Arabia’s National Cybersecurity Regulations.pdf
Bluechip Advanced Technologies
 
Reimaginando la Ciberdefensa: De Copilots a Redes de Agentes
Cristian Garcia G.
 
My Journey from CAD to BIM: A True Underdog Story
Safe Software
 
🚀 Let’s Build Our First Slack Workflow! 🔧.pdf
SanjeetMishra29
 
Enhancing Environmental Monitoring with Real-Time Data Integration: Leveragin...
Safe Software
 
Pipeline Industry IoT - Real Time Data Monitoring
Safe Software
 
Unlocking FME Flow’s Potential: Architecture Design for Modern Enterprises
Safe Software
 
Smarter Governance with AI: What Every Board Needs to Know
OnBoard
 
Optimizing the trajectory of a wheel loader working in short loading cycles
Reno Filla
 
Dev Dives: Accelerating agentic automation with Autopilot for Everyone
UiPathCommunity
 
99 Bottles of Trust on the Wall — Operational Principles for Trust in Cyber C...
treyka
 
Hello I'm "AI" Your New _________________
Dr. Tathagat Varma
 
5 Things to Consider When Deploying AI in Your Enterprise
Safe Software
 

Akka streams - Umeå java usergroup

  • 1. Akka streams Johan Andrén Umeå Java Usergroup, 2017-06-13
  • 3. Make building powerful concurrent & distributed applications simple. Akka is a toolkit and runtime for building highly concurrent, distributed, and resilient message-driven applications on the JVM 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 ??? 2015 JEP-266 inclusion in JDK9 Akka Streams, RxJava Vert.x, MongoDB, …
  • 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. When to use what abstraction modelling power complexity actors streams futures/cs java.concurrency
  • 20. Complete and awesome Java and Scala APIs (Just like everything in Akka) Akka Streams
  • 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); complete sources on github
  • 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); complete sources on github
  • 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: complete sources on github Source String Flow SinkString Integer Integer
  • 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() complete sources on github
  • 25. Akka Streams in ~20 seconds: Source.range(0, 20000000)
 .map(Object::toString)
 .runForeach(str -> System.out.println(str), materializer); complete sources on github
  • 26. Akka Streams in ~20 seconds: Source(0 to 20000000)
 .map(_.toString)
 .runForeach(println) complete sources on github
  • 27. Numbers as a service final Source<ByteString, NotUsed> numbers = Source.unfold(0L, n -> {
 long next = n + 1;
 return Optional.of(Pair.create(next, next));
 }).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); complete sources on github
  • 28. final Source<ByteString, NotUsed> numbers = Source.unfold(0L, n -> {
 long next = n + 1;
 return Optional.of(Pair.create(next, next));
 }).map(n -> ByteString.fromString(n.toString() + "n"));
 
 
 final Route route =
 path("numbers", () ->
 get(() ->
 complete(HttpResponse.create()
 .withStatus(StatusCodes.OK)
 .withEntity(HttpEntities.create(
 Numbers as a service complete sources on github
  • 29. return Optional.of(Pair.create(next, next));
 }).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); Numbers as a service complete sources on github
  • 30. Numbers as a service val numbers =
 Source.unfold(0L) { (n) =>
 val next = n + 1
 Some((next, next))
 }.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) complete sources on github
  • 31. recv buffer send buffer 🚚 🚚 🚚 🚚 🚚 🚚 🚚 Back pressure over TCP numbers TCP HTTP Server Client
  • 32. recv buffer send buffer 🚚 🚚 🚚 🚚 🚚 🚚 🚑 Back pressure over TCP numbers TCP HTTP Backpressure Server Client
  • 33. recv buffer send buffer 🚚 🚚 🚚 🚚 🚚 🚚 🚚 🚚 🚚 🚚 🚑 Back pressure over TCP numbers TCP HTTP Backpressure Backpressure Server Client
  • 34. A more useful example complete sources on github final Flow<Message, Message, NotUsed> measurementsFlow =
 Flow.of(Message.class)
 .flatMapConcat((Message message) ->
 message.asTextMessage()
 .getStreamedText()
 .fold("", (acc, elem) -> acc + elem)
 )
 .groupedWithin(1000, FiniteDuration.create(1, 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); Credit to: Colin Breck
  • 35. final Flow<Message, Message, NotUsed> measurementsFlow =
 Flow.of(Message.class)
 .flatMapConcat((Message message) ->
 message.asTextMessage()
 .getStreamedText()
 .fold("", (acc, elem) -> acc + elem)
 )
 .groupedWithin(1000, FiniteDuration.create(1, SECONDS))
 .mapAsync(5, database::asyncBulkInsert)
 .map(written ->
 TextMessage.create("wrote up to: " + written.get(written.size() - 1))
 );
 
 final Route route = path("measurements", () ->
 A more useful example complete sources on github Credit to: Colin Breck
  • 36. )
 .groupedWithin(1000, FiniteDuration.create(1, 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); A more useful example complete sources on github Credit to: Colin Breck
  • 37. A more useful example complete sources on github 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)
  • 38. The tale of the two pancake chefs HungrySink Frying Pan BatterSource Scoops of batter Pancakes nom nom nom asynchronous boundaries Roland Patrik
  • 39. Rolands pipelined pancakes HungrySinkPan 2BatterSource Pan 1 nom nom nom
  • 40. 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
  • 41. 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
  • 42. Patriks parallel pancakes HungrySink Pan 2 BatterSource Pan 1 Balance Merge nom nom nom
  • 43. 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
  • 44. 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
  • 45. Making pancakes together HungrySink Pan 3 BatterSource Pan 1 Balance Merge Pan 2 Pan 4 nom nom nom
  • 46. 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
  • 47. But I want to connect other things!
  • 48. A community for Akka Streams connectors http://github.com/akka/alpakka Alpakka
  • 49. Alpakka – a community for Stream connectors Existing Alpakka MQTT AMQP/ RabbitMQ SSE Cassandra FTP/ SFTP XML,CVS IronMq Files AWS DynamoDB AWS SNS,SQS, S3, Lambda JMS CSV TCP In Akka Actors Reactive Streams Java Streams Basic File IO External geode Azure Eventuate FS2 Akka Http HBase http://developer.lightbend.com/docs/alpakka/current/index.html Google Cloud Pub/Sub Camel Kafka
  • 50. But my usecase is a unique snowflake! ❄ ❄ ❄
  • 51. 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() {
 @Override
 public void onPush() throws Exception {
 push(out, f.apply(grab(in)));
 }
 });
 setHandler(out, new AbstractOutHandler() {
 @Override
 public void onPull() throws Exception {
 pull(in);
 }
 });
 }
 };
 }
 } complete sources on github
  • 52. 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() {
 @Override
 public void onPush() throws Exception {
 GraphStage API complete sources on github
  • 53. public FlowShape<A,B> shape() {
 return shape;
 }
 public GraphStageLogic createLogic(Attributes inheritedAttributes) {
 return new GraphStageLogic(shape) {
 {
 setHandler(in, new AbstractInHandler() {
 @Override
 public void onPush() throws Exception {
 push(out, f.apply(grab(in)));
 }
 });
 setHandler(out, new AbstractOutHandler() {
 @Override
 public void onPull() throws Exception {
 pull(in);
 }
 });
 }
 };
 }
 } GraphStage API complete sources on github
  • 54. 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")
 override val shape = FlowShape.of(in, out)
 
 override def createLogic(attr: Attributes): GraphStageLogic =
 new GraphStageLogic(shape) {
 setHandler(in, new InHandler {
 override def onPush(): Unit = {
 push(out, f(grab(in)))
 }
 })
 setHandler(out, new OutHandler {
 override def onPull(): Unit = {
 pull(in)
 }
 })
 }
 } complete sources on github
  • 55. The community Mailing list: https://groups.google.com/group/akka-user 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 ~200 active contributors!
  • 57. Tack för att ni lyssnade! @apnylle [email protected] github.com/johanandren All exempelkod (Java & Scala) https://github.com/johanandren/akka-stream-samples/tree/ume-jug http://akka.io Akka