From 4df5376dcb642df8753e7f492819f2b8608e0594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Andr=C3=A9n?= Date: Mon, 16 Dec 2019 15:01:45 +0100 Subject: [PATCH] Docs on fromSinkAndSource #25468 (#28349) --- .../main/paradox/images/fromSinkAndSource.png | Bin 0 -> 75395 bytes .../operators/Flow/fromSinkAndSource.md | 66 +++++++++++-- .../Flow/fromSinkAndSourceCoupled.md | 11 +-- .../operators/flow/FromSinkAndSource.java | 88 ++++++++++++++++++ .../operators/flow/FromSinkAndSource.scala | 77 +++++++++++++++ 5 files changed, 224 insertions(+), 18 deletions(-) create mode 100644 akka-docs/src/main/paradox/images/fromSinkAndSource.png create mode 100644 akka-docs/src/test/java/jdocs/stream/operators/flow/FromSinkAndSource.java create mode 100644 akka-docs/src/test/scala/docs/stream/operators/flow/FromSinkAndSource.scala diff --git a/akka-docs/src/main/paradox/images/fromSinkAndSource.png b/akka-docs/src/main/paradox/images/fromSinkAndSource.png new file mode 100644 index 0000000000000000000000000000000000000000..59a4d6f46817468630daf12b77e591e374f703c3 GIT binary patch literal 75395 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 GgeCwX(7Jp8 literal 0 HcmV?d00001 diff --git a/akka-docs/src/main/paradox/stream/operators/Flow/fromSinkAndSource.md b/akka-docs/src/main/paradox/stream/operators/Flow/fromSinkAndSource.md index a09e006eb5..b7d08ed73b 100644 --- a/akka-docs/src/main/paradox/stream/operators/Flow/fromSinkAndSource.md +++ b/akka-docs/src/main/paradox/stream/operators/Flow/fromSinkAndSource.md @@ -4,19 +4,65 @@ Creates a `Flow` from a `Sink` and a `Source` where the Flow's input will be sen @ref[Flow operators composed of Sinks and Sources](../index.md#flow-operators-composed-of-sinks-and-sources) -@@@div { .group-scala } - ## Signature -@@signature [Flow.scala](/akka-stream/src/main/scala/akka/stream/scaladsl/Flow.scala) { #fromSinkAndSource } - -@@@ +@apidoc[Flow.fromSinkAndSource](Flow$) { scala="#fromSinkAndSource[I,O](sink:akka.stream.Graph[akka.stream.SinkShape[I],_],source:akka.stream.Graph[akka.stream.SourceShape[O],_]):akka.stream.scaladsl.Flow[I,O,akka.NotUsed]" java="#fromSinkAndSource(akka.stream.Graph,akka.stream.Graph)" } ## Description -Creates a `Flow` from a `Sink` and a `Source` where the Flow's input will be sent to the `Sink` -and the `Flow` 's output will come from the Source. +Diagram -Note that termination events, like completion and cancelation is not automatically propagated through to the "other-side" -of the such-composed Flow. Use `Flow.fromSinkAndSourceCoupled` if you want to couple termination of both of the ends, -for example most useful in handling websocket connections. +`fromSinkAndSource` combines a separate `Sink` and `Source` into a `Flow`. + +Useful in many cases where an API requires a `Flow` but you want to provide a `Sink` and `Source` whose flows of elements are decoupled. + +Note that termination events, like completion and cancellation, are not automatically propagated through to the "other-side" of the such-composed `Flow`. The `Source` can complete and the sink will continue to accept elements. + +Use @ref:[fromSinkAndSourceCoupled](fromSinkAndSourceCoupled.md) if you want to couple termination of both of the ends. + +## Examples + +One use case is constructing a TCP server where requests and responses do not map 1:1 (like it does in the @ref[Echo TCP server sample](../../stream-io.md) where every incoming test is echoed back) but allows separate flows of elements from the client to the server and from the server to the client. + +This example `cancel`s the incoming stream, not allowing the client to write more messages, switching the TCP connection to "half-closed", but keeps streaming periodic output to the client: + +Scala +: @@snip [FromSinkAndSource.scala](/akka-docs/src/test/scala/docs/stream/operators/flow/FromSinkAndSource.scala) { #halfClosedTcpServer } + +Java +: @@snip [FromSinkAndSource.java](/akka-docs/src/test/java/jdocs/stream/operators/flow/FromSinkAndSource.java) { #halfClosedTcpServer } + +With this server running you could use `telnet 127.0.0.1 9999` to see a stream of timestamps being printed, one every second. + +The following sample is a little bit more advanced and uses the @apidoc[MergeHub] to dynamically merge incoming messages to a single stream which is then fed into a @apidoc[BroadcastHub] which emits elements over a dynamic set of downstreams allowing us to create a simplistic little TCP chat server in which a text entered from one client is emitted to all connected clients. + +Scala +: @@snip [FromSinkAndSource.scala](/akka-docs/src/test/scala/docs/stream/operators/flow/FromSinkAndSource.scala) { #chat } + +Java +: @@snip [FromSinkAndSource.java](/akka-docs/src/test/java/jdocs/stream/operators/flow/FromSinkAndSource.java) { #chat } + + +The same patterns can also be applied to @extref:[Akka HTTP WebSockets](akka.http:/server-side/websocket-support.html#server-api) which also have an API accepting a `Flow` of messages. + +If we would replace the `fromSinkAndSource` here with `fromSinkAndSourceCoupled` it would allow the client to close the connection by closing its outgoing stream. + +`fromSinkAndSource` can also be useful when testing a component that takes a `Flow` allowing for complete separate control and assertion of incoming and outgoing elements using stream testkit test probes for sink and source: + +Scala +: @@snip [FromSinkAndSource.scala](/akka-docs/src/test/scala/docs/stream/operators/flow/FromSinkAndSource.scala) { #testing } + +Java +: @@snip [FromSinkAndSource.java](/akka-docs/src/test/java/jdocs/stream/operators/flow/FromSinkAndSource.java) { #testing } + +## Reactive Streams semantics + +@@@div { .callout } + +**emits** when the `Source` emits + +**backpressures** when the `Sink` backpressures + +**completes** when the `Source` has completed and the `Sink` has cancelled. + +@@@ diff --git a/akka-docs/src/main/paradox/stream/operators/Flow/fromSinkAndSourceCoupled.md b/akka-docs/src/main/paradox/stream/operators/Flow/fromSinkAndSourceCoupled.md index 4e4b7c5d47..03ce607c68 100644 --- a/akka-docs/src/main/paradox/stream/operators/Flow/fromSinkAndSourceCoupled.md +++ b/akka-docs/src/main/paradox/stream/operators/Flow/fromSinkAndSourceCoupled.md @@ -4,20 +4,15 @@ Allows coupling termination (cancellation, completion, erroring) of Sinks and So @ref[Flow operators composed of Sinks and Sources](../index.md#flow-operators-composed-of-sinks-and-sources) -@@@div { .group-scala } - ## Signature -@@signature [Flow.scala](/akka-stream/src/main/scala/akka/stream/scaladsl/Flow.scala) { #fromSinkAndSourceCoupled } - -@@@ +@apidoc[Flow.fromSinkAndSourceCoupled](Flow$) { scala="#fromSinkAndSourceCoupled[I,O](sink:akka.stream.Graph[akka.stream.SinkShape[I],_],source:akka.stream.Graph[akka.stream.SourceShape[O],_]):akka.stream.scaladsl.Flow[I,O,akka.NotUsed]" java="#fromSinkAndSourceCoupled(akka.stream.Graph,akka.stream.Graph)" } ## Description -Allows coupling termination (cancellation, completion, erroring) of Sinks and Sources while creating a Flow between them. -Similar to `Flow.fromSinkAndSource` however couples the termination of these two operators. +See @ref[Flow.fromSinkAndSource](fromSinkAndSource.md) for docs on the general workings and examples. -E.g. if the emitted `Flow` gets a cancellation, the `Source` is cancelled, +This operator only adds coupled termination to what `fromSinkAndSource` does: If the emitted `Flow` gets a cancellation, the `Source` is cancelled, however the Sink will also be completed. The table below illustrates the effects in detail: | Returned Flow | Sink (in) | Source (out) | diff --git a/akka-docs/src/test/java/jdocs/stream/operators/flow/FromSinkAndSource.java b/akka-docs/src/test/java/jdocs/stream/operators/flow/FromSinkAndSource.java new file mode 100644 index 0000000000..e5fa69cf7b --- /dev/null +++ b/akka-docs/src/test/java/jdocs/stream/operators/flow/FromSinkAndSource.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2009-2019 Lightbend Inc. + */ + +package jdocs.stream.operators.flow; + +import akka.NotUsed; +import akka.actor.ActorSystem; +import akka.actor.Cancellable; +import akka.japi.Pair; +import akka.stream.javadsl.*; +import akka.stream.testkit.TestPublisher; +import akka.stream.testkit.TestSubscriber; +import akka.util.ByteString; +import org.reactivestreams.Publisher; +import org.reactivestreams.Subscriber; + +import java.time.Duration; +import java.util.concurrent.CompletionStage; + +public class FromSinkAndSource { + + void halfClosedTcpServer() { + ActorSystem system = null; + // #halfClosedTcpServer + // close in immediately + Sink sink = Sink.cancelled(); + // periodic tick out + Source source = + Source.tick(Duration.ofSeconds(1), Duration.ofSeconds(1), "tick") + .map(tick -> ByteString.fromString(System.currentTimeMillis() + "\n")); + + Flow serverFlow = Flow.fromSinkAndSource(sink, source); + + Source> connectionStream = + Tcp.get(system).bind("127.0.0.1", 9999); + + connectionStream.runForeach( + incomingConnection -> incomingConnection.handleWith(serverFlow, system), system); + // #halfClosedTcpServer + } + + void chat() { + ActorSystem system = null; + // #chat + Pair, Source> pair = + MergeHub.of(String.class).toMat(BroadcastHub.of(String.class), Keep.both()).run(system); + Sink sink = pair.first(); + Source source = pair.second(); + + Flow framing = + Framing.delimiter(ByteString.fromString("\n"), 1024); + + Sink sinkWithFraming = + framing.map(bytes -> bytes.utf8String()).to(pair.first()); + Source sourceWithFraming = + source.map(text -> ByteString.fromString(text + "\n")); + + Flow serverFlow = + Flow.fromSinkAndSource(sinkWithFraming, sourceWithFraming); + + Tcp.get(system) + .bind("127.0.0.1", 9999) + .runForeach( + incomingConnection -> incomingConnection.handleWith(serverFlow, system), system); + // #chat + } + + void myApiThatTakesAFlow(Flow flow) { + throw new UnsupportedOperationException(); + } + + void testing() { + ActorSystem system = null; + // #testing + TestSubscriber.Probe inProbe = TestSubscriber.probe(system); + TestPublisher.Probe outProbe = TestPublisher.probe(0, system); + Flow testFlow = + Flow.fromSinkAndSource(Sink.fromSubscriber(inProbe), Source.fromPublisher(outProbe)); + + myApiThatTakesAFlow(testFlow); + inProbe.expectNext("first"); + outProbe.expectRequest(); + outProbe.sendError(new RuntimeException("test error")); + // ... + // #testing + } +} diff --git a/akka-docs/src/test/scala/docs/stream/operators/flow/FromSinkAndSource.scala b/akka-docs/src/test/scala/docs/stream/operators/flow/FromSinkAndSource.scala new file mode 100644 index 0000000000..3b1bfabb03 --- /dev/null +++ b/akka-docs/src/test/scala/docs/stream/operators/flow/FromSinkAndSource.scala @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2009-2019 Lightbend Inc. + */ + +package docs.stream.operators.flow + +import akka.NotUsed +import akka.actor.ActorSystem +import akka.stream.scaladsl.BroadcastHub +import akka.stream.scaladsl.Flow +import akka.stream.scaladsl.Framing +import akka.stream.scaladsl.Keep +import akka.stream.scaladsl.MergeHub +import akka.stream.scaladsl.Sink +import akka.stream.scaladsl.Source +import akka.stream.scaladsl.Tcp +import akka.stream.testkit.TestPublisher +import akka.stream.testkit.TestSubscriber +import akka.stream.testkit.Utils.TE +import akka.stream.testkit.scaladsl.TestSource +import akka.stream.testkit.scaladsl.TestSink +import akka.util.ByteString + +import scala.concurrent.duration._ + +object FromSinkAndSource { + + implicit val system: ActorSystem = ??? + + def halfClosedTcpServer(): Unit = { + // #halfClosedTcpServer + // close in immediately + val sink = Sink.cancelled[ByteString] + // periodic tick out + val source = + Source.tick(1.second, 1.second, "tick").map(_ => ByteString(System.currentTimeMillis().toString + "\n")) + + val serverFlow = Flow.fromSinkAndSource(sink, source) + + Tcp().bind("127.0.0.1", 9999).runForeach { incomingConnection => + incomingConnection.handleWith(serverFlow) + } + // #halfClosedTcpServer + } + + def chat(): Unit = { + // #chat + val (sink, source) = MergeHub.source[String].toMat(BroadcastHub.sink[String])(Keep.both).run() + + val framing = Framing.delimiter(ByteString("\n"), 1024) + + val sinkWithFraming = framing.map(bytes => bytes.utf8String).to(sink) + val sourceWithFraming = source.map(text => ByteString(text + "\n")) + + val serverFlow = Flow.fromSinkAndSource(sinkWithFraming, sourceWithFraming) + + Tcp().bind("127.0.0.1", 9999).runForeach { incomingConnection => + incomingConnection.handleWith(serverFlow) + } + // #chat + } + + def testing(): Unit = { + def myApiThatTakesAFlow[In, Out](flow: Flow[In, Out, NotUsed]): Unit = ??? + // #testing + val inProbe = TestSubscriber.probe[String] + val outProbe = TestPublisher.probe[String]() + val testFlow = Flow.fromSinkAndSource(Sink.fromSubscriber(inProbe), Source.fromPublisher(outProbe)) + + myApiThatTakesAFlow(testFlow) + inProbe.expectNext("first") + outProbe.expectRequest() + outProbe.sendError(new RuntimeException("test error")) + // ... + // #testing + } +}