** Video of this talk is here: https://youtu.be/MQGXrrhGUTw **
The first talk of the Meetup on the 11th of April 2017, hosted by weeronline.nl in their Amsterdam offices.
Streams are everywhere! Akka Streams help us model streaming processes using a very descriptive DSL and optimising resource usage.
7. What is a stream?
A potentially unbounded stream of data that flows in
a sequential fashion from a Producer to a Consumer.
• Challenge 1: the consumer cannot predict how much
data it will need to handle
• Challenge 2: the speed of production and
consumption can be different
10. Advantages of applying back pressure
Sender can do other things while there are no requests
No overflowing buffers (the website will be slower but will stay up)
Less network traffic
…
13. What is Backpressure? (extra)
TOP DEFINITION
Pressure
A name for weed. A South Florida term.
"Yo, you got da pressure"
"Im rollin up da pressure"
14. The Reactive Streams standard
• “Reactive Streams” is a standardisation of dynamic
back pressure.
• Defines a minimal interface to make different systems
communicate with built-in back pressure.
• Applies to both runtime environments (JVM) &
network protocols.
http://www.reactive-streams.org
15. The Reactive Streams standard
You don’t need to know the internal semantics
(unless you want to provide an implementation)
20. The simplest stream (no Flow)
Source(1 to 10)
.to(Sink.foreach(println))
.run()
Source(1 to 10)
.runWith(Sink.foreach(println))
Source(1 to 10)
.runForeach(println)
21. The Simplest Stream (with Flow)
Source(1 to 100)
val multiplier = Flow[Int].map(_ * 2)
.runForeach(println).via(multiplier)
22. Source.tick(0.second, 1.second, randomString())
.via( )
.runForeach(println)
Akka Streams - More complex graphs
Broadcast
Append
“Fabio” to
string
Append
“Reactive”
to String
Evaluate
string
length
kindaUselessFlow
Print string
23. Akka Streams - More complex graphs
val myFlow: Flow[String, Int, NotUsed] = Flow.fromGraph(
GraphDSL.create() {
implicit builder =>
val fabioAppender = builder.add(Flow[String].map(s => s + "Fabio"))
val reactiveAppender = builder.add(Flow[String].map(s => s + "Reactive"))
val lengthFlow = builder.add(Flow[String].map(s => s.length))
val printSink: Sink[String, Future[Done]] = Sink.foreach(println)
val bcast = builder.add(Broadcast[String](2))
bcast ~> fabioAppender ~> lengthFlow
bcast ~> reactiveAppender ~> printSink
FlowShape(bcast.in, lengthFlow.out)
})
27. First approach: Actors
• Difficult to control resources (read: OOM exception)
• LOTS of messages, difficult to track and interpret logs
• Cascading timeouts
30. Advantages of Akka Streams
Average RAM usage down 40%
Back pressure is built in
Powerful native shapes (grouping, fan in/out..)
Debugging is a lot easier
Easier to handle failures (where is the problem?)
Reasonings about it is easier (overview!)
31. Lesson learned by others
https://tech.zalando.com/blog/comparing-akka-streams-actors-and-plain-futures
https://softwaremill.com/replacing-akka-actors-with-akka-streams/
https://sap1ens.com/blog/2015/10/25/actors-streams-and-futures-in-akka/