Docs for lazy stream operators (#28897)

This commit is contained in:
Johan Andrén 2020-05-15 12:03:27 +02:00 committed by GitHub
parent 5dc56a6d8c
commit ac3065bfad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 483 additions and 14 deletions

View file

@ -0,0 +1,69 @@
/*
* Copyright (C) 2009-2020 Lightbend Inc. <https://www.lightbend.com>
*/
package docs.stream.operators.flow
import java.util
import akka.actor.ActorSystem
import akka.stream.scaladsl.Flow
import akka.stream.scaladsl.Sink
import akka.stream.scaladsl.Source
object Lazy {
implicit val system: ActorSystem = ???
def example(): Unit = {
// #simple-example
val numbers = Source
.unfold(0) { n =>
val next = n + 1
println(s"Source producing $next")
Some((next, next))
}
.take(3)
val flow = Flow.lazyFlow { () =>
println("Creating the actual flow")
Flow[Int].map { element =>
println(s"Actual flow mapped $element")
element
}
}
numbers.via(flow).run()
// prints:
// Source producing 1
// Creating the actual flow
// Actual flow mapped 1
// Source producing 2
// Actual flow mapped 2
// #simple-example
}
def statefulMap(): Unit = {
// #mutable-example
val mutableFold = Flow.lazyFlow { () =>
val zero = new util.ArrayList[Int]()
Flow[Int].fold(zero) { (list, element) =>
list.add(element)
list
}
}
val stream =
Source(1 to 3).via(mutableFold).to(Sink.foreach(println))
stream.run()
stream.run()
stream.run()
// prints:
// [1, 2, 3]
// [1, 2, 3]
// [1, 2, 3]
// #mutable-example
}
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (C) 2009-2020 Lightbend Inc. <https://www.lightbend.com>
*/
package docs.stream.operators.sink
import akka.actor.ActorSystem
import akka.stream.scaladsl.Keep
import akka.stream.scaladsl.Sink
import akka.stream.scaladsl.Source
object Lazy {
implicit val system: ActorSystem = ???
def example(): Unit = {
// #simple-example
val matVal =
Source
.maybe[String]
.map { element =>
println(s"mapped $element")
element
}
.toMat(Sink.lazySink { () =>
println("Sink created")
Sink.foreach(elem => println(s"foreach $elem"))
})(Keep.left)
.run()
// some time passes
// nothing has been printed
matVal.success(Some("one"))
// now prints:
// mapped one
// Sink created
// foreach one
// #simple-example
}
}

View file

@ -0,0 +1,56 @@
/*
* Copyright (C) 2009-2020 Lightbend Inc. <https://www.lightbend.com>
*/
package docs.stream.operators.source
import akka.NotUsed
import akka.actor.ActorSystem
import akka.stream.scaladsl.Sink
import akka.stream.scaladsl.Source
object Lazy {
implicit val system: ActorSystem = ???
def createExpensiveSource(): Source[String, NotUsed] = ???
def notReallyThatLazy(): Unit = {
// #not-a-good-example
val source = Source.lazySource { () =>
println("Creating the actual source")
createExpensiveSource()
}
val queue = source.runWith(Sink.queue())
// ... time passes ...
// at some point in time we pull the first time
// but the source creation may already have been triggered
queue.pull()
// #not-a-good-example
}
class IteratorLikeThing {
def thereAreMore: Boolean = ???
def extractNext: String = ???
}
def safeMutableSource(): Unit = {
// #one-per-materialization
val stream = Source
.lazySource { () =>
val iteratorLike = new IteratorLikeThing
Source.unfold(iteratorLike) { iteratorLike =>
if (iteratorLike.thereAreMore) Some((iteratorLike, iteratorLike.extractNext))
else None
}
}
.to(Sink.foreach(println))
// each of the three materializations will have their own instance of IteratorLikeThing
stream.run()
stream.run()
stream.run()
// #one-per-materialization
}
}