!str #19037 rename FlowGraph to GraphDSL

This commit is contained in:
Roland Kuhn 2015-11-30 15:45:37 +01:00
parent 5895834d98
commit f00da4daac
92 changed files with 535 additions and 542 deletions

View file

@ -20,8 +20,8 @@ object MaterializationBenchmark {
} }
val graphWithJunctionsBuilder = (numOfJunctions: Int) => val graphWithJunctionsBuilder = (numOfJunctions: Int) =>
RunnableGraph.fromGraph(FlowGraph.create() { implicit b => RunnableGraph.fromGraph(GraphDSL.create() { implicit b =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val broadcast = b.add(Broadcast[Unit](numOfJunctions)) val broadcast = b.add(Broadcast[Unit](numOfJunctions))
var outlet = broadcast.out(0) var outlet = broadcast.out(0)
@ -40,23 +40,23 @@ object MaterializationBenchmark {
val graphWithNestedImportsBuilder = (numOfNestedGraphs: Int) => { val graphWithNestedImportsBuilder = (numOfNestedGraphs: Int) => {
var flow: Graph[FlowShape[Unit, Unit], Unit] = Flow[Unit].map(identity) var flow: Graph[FlowShape[Unit, Unit], Unit] = Flow[Unit].map(identity)
for (_ <- 1 to numOfNestedGraphs) { for (_ <- 1 to numOfNestedGraphs) {
flow = FlowGraph.create(flow) { b flow = GraphDSL.create(flow) { b
flow flow
FlowShape(flow.inlet, flow.outlet) FlowShape(flow.inlet, flow.outlet)
} }
} }
RunnableGraph.fromGraph(FlowGraph.create(flow) { implicit b RunnableGraph.fromGraph(GraphDSL.create(flow) { implicit b
flow flow
import FlowGraph.Implicits._ import GraphDSL.Implicits._
Source.single(()) ~> flow ~> Sink.ignore Source.single(()) ~> flow ~> Sink.ignore
ClosedShape ClosedShape
}) })
} }
val graphWithImportedFlowBuilder = (numOfFlows: Int) => val graphWithImportedFlowBuilder = (numOfFlows: Int) =>
RunnableGraph.fromGraph(FlowGraph.create(Source.single(())) { implicit b source RunnableGraph.fromGraph(GraphDSL.create(Source.single(())) { implicit b source
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val flow = Flow[Unit].map(identity) val flow = Flow[Unit].map(identity)
var outlet: Outlet[Unit] = source.outlet var outlet: Outlet[Unit] = source.outlet
for (i <- 0 until numOfFlows) { for (i <- 0 until numOfFlows) {

View file

@ -80,12 +80,12 @@ public class MigrationsJava {
{ {
//#graph-create //#graph-create
FlowGraph.create(builder -> { GraphDSL.create(builder -> {
//... //...
return ClosedShape.getInstance(); return ClosedShape.getInstance();
}); });
FlowGraph.create(builder -> { GraphDSL.create(builder -> {
//... //...
return new FlowShape<>(inlet, outlet); return new FlowShape<>(inlet, outlet);
}); });
@ -94,22 +94,22 @@ public class MigrationsJava {
{ {
//#graph-create-2 //#graph-create-2
FlowGraph.create(builder -> { GraphDSL.create(builder -> {
//... //...
return SourceShape.of(outlet); return SourceShape.of(outlet);
}); });
FlowGraph.create(builder -> { GraphDSL.create(builder -> {
//... //...
return SinkShape.of(inlet); return SinkShape.of(inlet);
}); });
FlowGraph.create(builder -> { GraphDSL.create(builder -> {
//... //...
return FlowShape.of(inlet, outlet); return FlowShape.of(inlet, outlet);
}); });
FlowGraph.create(builder -> { GraphDSL.create(builder -> {
//... //...
return BidiShape.of(inlet1, outlet1, inlet2, outlet2); return BidiShape.of(inlet1, outlet1, inlet2, outlet2);
}); });
@ -118,7 +118,7 @@ public class MigrationsJava {
{ {
//#graph-builder //#graph-builder
FlowGraph.create(builder -> { GraphDSL.create(builder -> {
builder.from(outlet).toInlet(inlet); builder.from(outlet).toInlet(inlet);
builder.from(outlet).via(builder.add(flow)).toInlet(inlet); builder.from(outlet).via(builder.add(flow)).toInlet(inlet);
builder.from(builder.add(Source.single(0))).to(builder.add(Sink.head())); builder.from(builder.add(Source.single(0))).to(builder.add(Sink.head()));

View file

@ -86,18 +86,20 @@ Should be replaced by
.. includecode:: code/docs/MigrationsJava.java#bidi-wrap .. includecode:: code/docs/MigrationsJava.java#bidi-wrap
FlowGraph builder methods have been renamed FlowGraph class and builder methods have been renamed
=========================================== =====================================================
Due to incorrect overlap with the :class:`Flow` concept we renamed the :class:`FlowGraph` class to :class:`GraphDSL`.
There is now only one graph creation method called ``create`` which is analogous to the old ``partial`` method. For There is now only one graph creation method called ``create`` which is analogous to the old ``partial`` method. For
closed graphs now it is explicitly required to return ``ClosedShape`` at the end of the builder block. closed graphs now it is explicitly required to return ``ClosedShape`` at the end of the builder block.
Update procedure Update procedure
---------------- ----------------
1. Replace all occurrences of ``FlowGraph.partial()`` or ``FlowGraph.closed()`` with ``FlowGraph.create()`` 1. Search and replace all occurrences of ``FlowGraph`` with ``GraphDSL``.
2. Add ``ClosedShape`` as a return value of the builder block if it was ``FlowGraph.closed()`` before 2. Replace all occurrences of ``GraphDSL.partial()`` or ``GraphDSL.closed()`` with ``GraphDSL.create()``.
3. Wrap the closed graph with ``RunnableGraph.fromGraph`` if it was ``FlowGraph.closed()`` before 3. Add ``ClosedShape`` as a return value of the builder block if it was ``FlowGraph.closed()`` before.
4. Wrap the closed graph with ``RunnableGraph.fromGraph`` if it was ``FlowGraph.closed()`` before.
Example Example
^^^^^^^ ^^^^^^^
@ -125,7 +127,7 @@ Methods that create Source, Sink, Flow from Graphs have been removed
Previously there were convenience methods available on ``Sink``, ``Source``, ``Flow`` an ``BidiFlow`` to create Previously there were convenience methods available on ``Sink``, ``Source``, ``Flow`` an ``BidiFlow`` to create
these DSL elements from a graph builder directly. Now this requires two explicit steps to reduce the number of overloaded these DSL elements from a graph builder directly. Now this requires two explicit steps to reduce the number of overloaded
methods (helps Java 8 type inference) and also reduces the ways how these elements can be created. There is only one methods (helps Java 8 type inference) and also reduces the ways how these elements can be created. There is only one
graph creation method to learn (``FlowGraph.create``) and then there is only one conversion method to use ``fromGraph()``. graph creation method to learn (``GraphDSL.create``) and then there is only one conversion method to use ``fromGraph()``.
This means that the following methods have been removed: This means that the following methods have been removed:
- ``adapt()`` method on ``Source``, ``Sink``, ``Flow`` and ``BidiFlow`` (both DSLs) - ``adapt()`` method on ``Source``, ``Sink``, ``Flow`` and ``BidiFlow`` (both DSLs)
@ -138,7 +140,7 @@ Update procedure
Everywhere where ``Source``, ``Sink``, ``Flow`` and ``BidiFlow`` is created from a graph using a builder have to Everywhere where ``Source``, ``Sink``, ``Flow`` and ``BidiFlow`` is created from a graph using a builder have to
be replaced with two steps be replaced with two steps
1. Create a ``Graph`` with the correct ``Shape`` using ``FlowGraph.create`` (e.g.. for ``Source`` it means first 1. Create a ``Graph`` with the correct ``Shape`` using ``GraphDSL.create`` (e.g.. for ``Source`` it means first
creating a ``Graph`` with ``SourceShape``) creating a ``Graph`` with ``SourceShape``)
2. Create the required DSL element by calling ``fromGraph()`` on the required DSL element (e.g. ``Source.fromGraph``) 2. Create the required DSL element by calling ``fromGraph()`` on the required DSL element (e.g. ``Source.fromGraph``)
passing the graph created in the previous step passing the graph created in the previous step

View file

@ -126,7 +126,7 @@ As a first example, let's look at a more complex layout:
The diagram shows a :class:`RunnableGraph` (remember, if there are no unwired ports, the graph is closed, and therefore The diagram shows a :class:`RunnableGraph` (remember, if there are no unwired ports, the graph is closed, and therefore
can be materialized) that encapsulates a non-trivial stream processing network. It contains fan-in, fan-out stages, can be materialized) that encapsulates a non-trivial stream processing network. It contains fan-in, fan-out stages,
directed and non-directed cycles. The ``runnable()`` method of the :class:`FlowGraph` factory object allows the creation of a directed and non-directed cycles. The ``runnable()`` method of the :class:`GraphDSL` factory object allows the creation of a
general, closed, and runnable graph. For example the network on the diagram can be realized like this: general, closed, and runnable graph. For example the network on the diagram can be realized like this:
.. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/CompositionDocTest.java#complex-graph .. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/CompositionDocTest.java#complex-graph
@ -140,7 +140,7 @@ It is possible to refer to the ports, so another version might look like this:
Similar to the case in the first section, so far we have not considered modularity. We created a complex graph, but Similar to the case in the first section, so far we have not considered modularity. We created a complex graph, but
the layout is flat, not modularized. We will modify our example, and create a reusable component with the graph DSL. the layout is flat, not modularized. We will modify our example, and create a reusable component with the graph DSL.
The way to do it is to use the ``create()`` method on :class:`FlowGraph` factory. If we remove the sources and sinks The way to do it is to use the ``create()`` method on :class:`GraphDSL` factory. If we remove the sources and sinks
from the previous example, what remains is a partial graph: from the previous example, what remains is a partial graph:
| |
@ -283,7 +283,7 @@ Attributes
---------- ----------
We have seen that we can use ``named()`` to introduce a nesting level in the fluid DSL (and also explicit nesting by using We have seen that we can use ``named()`` to introduce a nesting level in the fluid DSL (and also explicit nesting by using
``create()`` from :class:`FlowGraph`). Apart from having the effect of adding a nesting level, ``named()`` is actually ``create()`` from :class:`GraphDSL`). Apart from having the effect of adding a nesting level, ``named()`` is actually
a shorthand for calling ``withAttributes(Attributes.name("someName"))``. Attributes provide a way to fine-tune certain a shorthand for calling ``withAttributes(Attributes.name("someName"))``. Attributes provide a way to fine-tune certain
aspects of the materialized running entity. For example buffer sizes can be controlled via attributes (see aspects of the materialized running entity. For example buffer sizes can be controlled via attributes (see
:ref:`stream-buffers-scala`). When it comes to hierarchic composition, attributes are inherited by nested modules, :ref:`stream-buffers-scala`). When it comes to hierarchic composition, attributes are inherited by nested modules,

View file

@ -15,7 +15,7 @@ Custom processing with GraphStage
================================= =================================
The :class:`GraphStage` abstraction can be used to create arbitrary graph processing stages with any number of input The :class:`GraphStage` abstraction can be used to create arbitrary graph processing stages with any number of input
or output ports. It is a counterpart of the ``FlowGraph.create()`` method which creates new stream processing or output ports. It is a counterpart of the ``GraphDSL.create()`` method which creates new stream processing
stages by composing others. Where :class:`GraphStage` differs is that it creates a stage that is itself not divisible into stages by composing others. Where :class:`GraphStage` differs is that it creates a stage that is itself not divisible into
smaller ones, and allows state to be maintained inside it in a safe way. smaller ones, and allows state to be maintained inside it in a safe way.

View file

@ -31,8 +31,11 @@ Back-pressure
Non-Blocking Non-Blocking
Means that a certain operation does not hinder the progress of the calling thread, even if it takes long time to Means that a certain operation does not hinder the progress of the calling thread, even if it takes long time to
finish the requested operation. finish the requested operation.
Graph
A description of a stream processing topology, defining the pathways through which elements shall flow when the stream
is running.
Processing Stage Processing Stage
The common name for all building blocks that build up a Flow or FlowGraph. The common name for all building blocks that build up a Graph.
Examples of a processing stage would be operations like ``map()``, ``filter()``, stages added by ``transform()`` like Examples of a processing stage would be operations like ``map()``, ``filter()``, stages added by ``transform()`` like
:class:`PushStage`, :class:`PushPullStage`, :class:`StatefulStage` and graph junctions like ``Merge`` or ``Broadcast``. :class:`PushStage`, :class:`PushPullStage`, :class:`StatefulStage` and graph junctions like ``Merge`` or ``Broadcast``.
For the full list of built-in processing stages see :ref:`stages-overview` For the full list of built-in processing stages see :ref:`stages-overview`
@ -67,7 +70,7 @@ it will be represented by the ``RunnableGraph`` type, indicating that it is read
It is important to remember that even after constructing the ``RunnableGraph`` by connecting all the source, sink and It is important to remember that even after constructing the ``RunnableGraph`` by connecting all the source, sink and
different processing stages, no data will flow through it until it is materialized. Materialization is the process of different processing stages, no data will flow through it until it is materialized. Materialization is the process of
allocating all resources needed to run the computation described by a Flow (in Akka Streams this will often involve allocating all resources needed to run the computation described by a Graph (in Akka Streams this will often involve
starting up Actors). Thanks to Flows being simply a description of the processing pipeline they are *immutable, starting up Actors). Thanks to Flows being simply a description of the processing pipeline they are *immutable,
thread-safe, and freely shareable*, which means that it is for example safe to share and send them between actors, to have thread-safe, and freely shareable*, which means that it is for example safe to share and send them between actors, to have
one actor prepare the work, and then have it be materialized at some completely different place in the code. one actor prepare the work, and then have it be materialized at some completely different place in the code.
@ -200,11 +203,11 @@ Stream Materialization
When constructing flows and graphs in Akka Streams think of them as preparing a blueprint, an execution plan. When constructing flows and graphs in Akka Streams think of them as preparing a blueprint, an execution plan.
Stream materialization is the process of taking a stream description (the graph) and allocating all the necessary resources Stream materialization is the process of taking a stream description (the graph) and allocating all the necessary resources
it needs in order to run. In the case of Akka Streams this often means starting up Actors which power the processing, it needs in order to run. In the case of Akka Streams this often means starting up Actors which power the processing,
but is not restricted to that - it could also mean opening files or socket connections etc. depending on what the stream needs. but is not restricted to that—it could also mean opening files or socket connections etc.—depending on what the stream needs.
Materialization is triggered at so called "terminal operations". Most notably this includes the various forms of the ``run()`` Materialization is triggered at so called "terminal operations". Most notably this includes the various forms of the ``run()``
and ``runWith()`` methods defined on flow elements as well as a small number of special syntactic sugars for running with and ``runWith()`` methods defined on :class:`Source` or :class:`Flow` elements as well as a small number of special syntactic sugars for running with
well-known sinks, such as ``runForeach(el -> )`` (being an alias to ``runWith(Sink.foreach(el -> ))``. well-known sinks, such as ``runForeach(el -> ...)`` (being an alias to ``runWith(Sink.foreach(el -> ...))``.
Materialization is currently performed synchronously on the materializing thread. Materialization is currently performed synchronously on the materializing thread.
The actual stream processing is handled by actors started up during the streams materialization, The actual stream processing is handled by actors started up during the streams materialization,
@ -212,7 +215,7 @@ which will be running on the thread pools they have been configured to run on -
:class:`MaterializationSettings` while constructing the :class:`ActorMaterializer`. :class:`MaterializationSettings` while constructing the :class:`ActorMaterializer`.
.. note:: .. note::
Reusing *instances* of linear computation stages (Source, Sink, Flow) inside FlowGraphs is legal, Reusing *instances* of linear computation stages (Source, Sink, Flow) inside composite Graphs is legal,
yet will materialize that stage multiple times. yet will materialize that stage multiple times.
.. _flow-combine-mat-java: .. _flow-combine-mat-java:

View file

@ -17,9 +17,10 @@ streams, such that the second one is consumed after the first one has completed)
.. _flow-graph-java: .. _flow-graph-java:
Constructing Flow Graphs Constructing Graphs
------------------------ -------------------
Flow graphs are built from simple Flows which serve as the linear connections within the graphs as well as junctions
Graphs are built from simple Flows which serve as the linear connections within the graphs as well as junctions
which serve as fan-in and fan-out points for Flows. Thanks to the junctions having meaningful types based on their behaviour which serve as fan-in and fan-out points for Flows. Thanks to the junctions having meaningful types based on their behaviour
and making them explicit elements these elements should be rather straightforward to use. and making them explicit elements these elements should be rather straightforward to use.
@ -40,7 +41,7 @@ Akka Streams currently provide these junctions (for a detailed list see :ref:`st
- ``Zip<A,B>`` *(2 inputs, 1 output)* is a :class:`ZipWith` specialised to zipping input streams of ``A`` and ``B`` into a ``Pair(A,B)`` tuple stream - ``Zip<A,B>`` *(2 inputs, 1 output)* is a :class:`ZipWith` specialised to zipping input streams of ``A`` and ``B`` into a ``Pair(A,B)`` tuple stream
- ``Concat<A>`` *(2 inputs, 1 output)* concatenates two streams (first consume one, then the second one) - ``Concat<A>`` *(2 inputs, 1 output)* concatenates two streams (first consume one, then the second one)
One of the goals of the FlowGraph DSL is to look similar to how one would draw a graph on a whiteboard, so that it is One of the goals of the GraphDSL DSL is to look similar to how one would draw a graph on a whiteboard, so that it is
simple to translate a design from whiteboard to code and be able to relate those two. Let's illustrate this by translating simple to translate a design from whiteboard to code and be able to relate those two. Let's illustrate this by translating
the below hand drawn graph into Akka Streams: the below hand drawn graph into Akka Streams:
@ -53,15 +54,14 @@ or ending a :class:`Flow`.
.. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/FlowGraphDocTest.java#simple-flow-graph .. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/FlowGraphDocTest.java#simple-flow-graph
.. note:: .. note::
Junction *reference equality* defines *graph node equality* (i.e. the same merge *instance* used in a FlowGraph Junction *reference equality* defines *graph node equality* (i.e. the same merge *instance* used in a GraphDSL
refers to the same location in the resulting graph). refers to the same location in the resulting graph).
By looking at the snippets above, it should be apparent that the ``builder`` object is *mutable*. By looking at the snippets above, it should be apparent that the ``builder`` object is *mutable*.
The reason for this design choice is to enable simpler creation of complex graphs, which may even contain cycles. The reason for this design choice is to enable simpler creation of complex graphs, which may even contain cycles.
Once the FlowGraph has been constructed though, the :class:`RunnableGraph` instance *is immutable, thread-safe, and freely shareable*. Once the GraphDSL has been constructed though, the :class:`RunnableGraph` instance *is immutable, thread-safe, and freely shareable*.
The same is true of all flow pieces—sources, sinks, and flows—once they are constructed. The same is true of all graph pieces—sources, sinks, and flows—once they are constructed.
This means that you can safely re-use one given Flow in multiple places in a processing graph. This means that you can safely re-use one given Flow or junction in multiple places in a processing graph.
We have seen examples of such re-use already above: the merge and broadcast junctions were imported We have seen examples of such re-use already above: the merge and broadcast junctions were imported
into the graph using ``builder.add(...)``, an operation that will make a copy of the blueprint that into the graph using ``builder.add(...)``, an operation that will make a copy of the blueprint that
@ -79,17 +79,17 @@ materialized as two connections between the corresponding Sources and Sinks:
.. _partial-flow-graph-java: .. _partial-flow-graph-java:
Constructing and combining Partial Flow Graphs Constructing and combining Partial Graphs
---------------------------------------------- -----------------------------------------
Sometimes it is not possible (or needed) to construct the entire computation graph in one place, but instead construct Sometimes it is not possible (or needed) to construct the entire computation graph in one place, but instead construct
all of its different phases in different places and in the end connect them all into a complete graph and run it. all of its different phases in different places and in the end connect them all into a complete graph and run it.
This can be achieved by using the returned :class:`Graph` from ``FlowGraph.create()`` rather than This can be achieved by using the returned :class:`Graph` from ``GraphDSL.create()`` rather than
passing it to ``RunnableGraph.fromGraph()`` to wrap it in a :class:`RunnableGraph`.The reason of representing it as a different type is that a passing it to ``RunnableGraph.fromGraph()`` to wrap it in a :class:`RunnableGraph`.The reason of representing it as a different type is that a
:class:`RunnableGraph` requires all ports to be connected, and if they are not :class:`RunnableGraph` requires all ports to be connected, and if they are not
it will throw an exception at construction time, which helps to avoid simple it will throw an exception at construction time, which helps to avoid simple
wiring errors while working with graphs. A partial flow graph however allows wiring errors while working with graphs. A partial graph however allows
you to return the set of yet to be connected ports from the code block that you to return the set of yet to be connected ports from the code block that
performs the internal wiring. performs the internal wiring.
@ -105,10 +105,10 @@ then we import it (all of its nodes and connections) explicitly into the last gr
the undefined elements are rewired to real sources and sinks. The graph can then be run and yields the expected result. the undefined elements are rewired to real sources and sinks. The graph can then be run and yields the expected result.
.. warning:: .. warning::
Please note that :class:`FlowGraph` is not able to provide compile time type-safety about whether or not all Please note that :class:`GraphDSL` is not able to provide compile time type-safety about whether or not all
elements have been properly connected—this validation is performed as a runtime check during the graph's instantiation. elements have been properly connected—this validation is performed as a runtime check during the graph's instantiation.
A partial flow graph also verifies that all ports are either connected or part of the returned :class:`Shape`. A partial graph also verifies that all ports are either connected or part of the returned :class:`Shape`.
.. _constructing-sources-sinks-flows-from-partial-graphs-java: .. _constructing-sources-sinks-flows-from-partial-graphs-java:
@ -129,7 +129,7 @@ Being able to hide complex graphs inside of simple elements such as Sink / Sourc
complex element and from there on treat it as simple compound stage for linear computations. complex element and from there on treat it as simple compound stage for linear computations.
In order to create a Source from a graph the method ``Source.fromGraph`` is used, to use it we must have a In order to create a Source from a graph the method ``Source.fromGraph`` is used, to use it we must have a
``Graph`` with a ``SourceShape``. This is constructed using ``FlowGraph.create`` and providing building a ``SourceShape`` ``Graph`` with a ``SourceShape``. This is constructed using ``GraphDSL.create`` and providing building a ``SourceShape``
graph. The single outlet must be provided to the ``SourceShape.of`` method and will become “the sink that must graph. The single outlet must be provided to the ``SourceShape.of`` method and will become “the sink that must
be attached before this Source can run”. be attached before this Source can run”.
@ -231,7 +231,7 @@ The following example demonstrates a case where the materialized ``Future`` of a
Graph cycles, liveness and deadlocks Graph cycles, liveness and deadlocks
------------------------------------ ------------------------------------
Cycles in bounded flow graphs need special considerations to avoid potential deadlocks and other liveness issues. Cycles in bounded stream topologies need special considerations to avoid potential deadlocks and other liveness issues.
This section shows several examples of problems that can arise from the presence of feedback arcs in stream processing This section shows several examples of problems that can arise from the presence of feedback arcs in stream processing
graphs. graphs.

View file

@ -86,10 +86,10 @@ it makes sense to make the Server initiate the conversation by emitting a "hello
.. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/io/StreamTcpDocTest.java#welcome-banner-chat-server .. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/io/StreamTcpDocTest.java#welcome-banner-chat-server
The way we constructed a :class:`Flow` using a :class:`PartialFlowGraph` is explained in detail in The way we constructed a :class:`Flow` using the :class:`GraphDSL` is explained in detail in
:ref:`constructing-sources-sinks-flows-from-partial-graphs-java`, however the basic concepts is rather simple :ref:`constructing-sources-sinks-flows-from-partial-graphs-java`, however the basic concepts is rather simple
we can encapsulate arbitrarily complex logic within a :class:`Flow` as long as it exposes the same interface, which means we can encapsulate arbitrarily complex logic within a :class:`Flow` as long as it exposes the same interface, which means
exposing exactly one :class:`UndefinedSink` and exactly one :class:`UndefinedSource` which will be connected to the TCP exposing exactly one :class:`Outlet` and exactly one :class:`Inlet` which will be connected to the TCP
pipeline. In this example we use a :class:`Concat` graph processing stage to inject the initial message, and then pipeline. In this example we use a :class:`Concat` graph processing stage to inject the initial message, and then
continue with handling all incoming data using the echo handler. You should use this pattern of encapsulating complex continue with handling all incoming data using the echo handler. You should use this pattern of encapsulating complex
logic in Flows and attaching those to :class:`StreamIO` in order to implement your custom and possibly sophisticated TCP servers. logic in Flows and attaching those to :class:`StreamIO` in order to implement your custom and possibly sophisticated TCP servers.

View file

@ -107,13 +107,13 @@ Akka Streams intentionally separate the linear stream structures (Flows) from th
in order to offer the most convenient API for both of these cases. Graphs can express arbitrarily complex stream setups in order to offer the most convenient API for both of these cases. Graphs can express arbitrarily complex stream setups
at the expense of not reading as familiarly as collection transformations. at the expense of not reading as familiarly as collection transformations.
Graphs are constructed using :class:`FlowGraph` like this: Graphs are constructed using :class:`GraphDSL` like this:
.. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/TwitterStreamQuickstartDocTest.java#flow-graph-broadcast .. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/TwitterStreamQuickstartDocTest.java#flow-graph-broadcast
As you can see, we use graph builder ``b`` to construct the graph using ``UniformFanOutShape`` and ``Flow`` s. As you can see, we use graph builder ``b`` to construct the graph using ``UniformFanOutShape`` and ``Flow`` s.
``FlowGraph.create`` returns a :class:`Graph`, in this example a ``Graph<ClosedShape,Unit>`` where ``GraphDSL.create`` returns a :class:`Graph`, in this example a ``Graph<ClosedShape,Unit>`` where
:class:`ClosedShape` means that it is *a fully connected graph* or "closed" - there are no unconnected inputs or outputs. :class:`ClosedShape` means that it is *a fully connected graph* or "closed" - there are no unconnected inputs or outputs.
Since it is closed it is possible to transform the graph into a :class:`RunnableGraph` using ``RunnableGraph.fromGraph``. Since it is closed it is possible to transform the graph into a :class:`RunnableGraph` using ``RunnableGraph.fromGraph``.
The runnable graph can then be ``run()`` to materialize a stream out of it. The runnable graph can then be ``run()`` to materialize a stream out of it.

View file

@ -141,15 +141,15 @@ Rate transformation
Understanding conflate Understanding conflate
---------------------- ----------------------
When a fast producer can not be informed to slow down by backpressure or some other signal, conflate might be useful to combine elements from a producer until a demand signal comes from a consumer. When a fast producer can not be informed to slow down by backpressure or some other signal, ``conflate`` might be useful to combine elements from a producer until a demand signal comes from a consumer.
Below is an example snippet that summarizes fast stream of elements to a standart deviation, mean and count of elements that have arrived while the stats have been calculated. Below is an example snippet that summarizes fast stream of elements to a standart deviation, mean and count of elements that have arrived while the stats have been calculated.
.. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/RateTransformationDocTest.java#conflate-summarize .. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/RateTransformationDocTest.java#conflate-summarize
This example demonstrates that such flow's rate is decoupled. Element rate at the start of the flow can be much higher that the element rate at the end of the flow. This example demonstrates that such flow's rate is decoupled. The element rate at the start of the flow can be much higher that the element rate at the end of the flow.
Another possible use of conflate is to not consider all elements for summary when producer starts getting too fast. Example below demonstrates how conflate can be used to implement random drop of elements when consumer is not able to keep up with the producer. Another possible use of ``conflate`` is to not consider all elements for summary when producer starts getting too fast. Example below demonstrates how ``conflate`` can be used to implement random drop of elements when consumer is not able to keep up with the producer.
.. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/RateTransformationDocTest.java#conflate-sample .. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/RateTransformationDocTest.java#conflate-sample
@ -158,7 +158,7 @@ Understanding expand
Expand helps to deal with slow producers which are unable to keep up with the demand coming from consumers. Expand allows to extrapolate a value to be sent as an element to a consumer. Expand helps to deal with slow producers which are unable to keep up with the demand coming from consumers. Expand allows to extrapolate a value to be sent as an element to a consumer.
As a simple use of expand here is a flow that sends the same element to consumer when producer does not send any new elements. As a simple use of ``expand`` here is a flow that sends the same element to consumer when producer does not send any new elements.
.. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/RateTransformationDocTest.java#expand-last .. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/RateTransformationDocTest.java#expand-last
@ -166,4 +166,4 @@ Expand also allows to keep some state between demand requests from the downstrea
.. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/RateTransformationDocTest.java#expand-drift .. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/RateTransformationDocTest.java#expand-drift
Note that all of the elements coming from upstream will go through expand at least once. This means that the output of this flow is going to report a drift of zero if producer is fast enough, or a larger drift otherwise. Note that all of the elements coming from upstream will go through ``expand`` at least once. This means that the output of this flow is going to report a drift of zero if producer is fast enough, or a larger drift otherwise.

View file

@ -51,14 +51,14 @@ class MigrationsScala extends AkkaSpec {
//#bidiflow-wrap //#bidiflow-wrap
//#graph-create //#graph-create
// Replaces FlowGraph.closed() // Replaces GraphDSL.closed()
FlowGraph.create() { builder => GraphDSL.create() { builder =>
//... //...
ClosedShape ClosedShape
} }
// Replaces FlowGraph.partial() // Replaces GraphDSL.partial()
FlowGraph.create() { builder => GraphDSL.create() { builder =>
//... //...
FlowShape(inlet, outlet) FlowShape(inlet, outlet)
} }
@ -66,25 +66,25 @@ class MigrationsScala extends AkkaSpec {
//#graph-create-2 //#graph-create-2
Source.fromGraph( Source.fromGraph(
FlowGraph.create() { builder => GraphDSL.create() { builder =>
//... //...
SourceShape(outlet) SourceShape(outlet)
}) })
Sink.fromGraph( Sink.fromGraph(
FlowGraph.create() { builder => GraphDSL.create() { builder =>
//... //...
SinkShape(inlet) SinkShape(inlet)
}) })
Flow.fromGraph( Flow.fromGraph(
FlowGraph.create() { builder => GraphDSL.create() { builder =>
//... //...
FlowShape(inlet, outlet) FlowShape(inlet, outlet)
}) })
BidiFlow.fromGraph( BidiFlow.fromGraph(
FlowGraph.create() { builder => GraphDSL.create() { builder =>
//... //...
BidiShape(inlet1, outlet1, inlet2, outlet2) BidiShape(inlet1, outlet1, inlet2, outlet2)
}) })
@ -92,8 +92,8 @@ class MigrationsScala extends AkkaSpec {
//#graph-edges //#graph-edges
RunnableGraph.fromGraph( RunnableGraph.fromGraph(
FlowGraph.create() { implicit builder => GraphDSL.create() { implicit builder =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
outlet ~> inlet outlet ~> inlet
outlet ~> flow ~> inlet outlet ~> flow ~> inlet
//... //...

View file

@ -44,7 +44,7 @@ object BidiFlowDocSpec {
} }
//#codec-impl //#codec-impl
val codecVerbose = BidiFlow.fromGraph(FlowGraph.create() { b => val codecVerbose = BidiFlow.fromGraph(GraphDSL.create() { b =>
// construct and add the top flow, going outbound // construct and add the top flow, going outbound
val outbound = b.add(Flow[Message].map(toBytes)) val outbound = b.add(Flow[Message].map(toBytes))
// construct and add the bottom flow, going inbound // construct and add the bottom flow, going inbound
@ -58,7 +58,7 @@ object BidiFlowDocSpec {
//#codec //#codec
//#framing //#framing
val framing = BidiFlow.fromGraph(FlowGraph.create() { b => val framing = BidiFlow.fromGraph(GraphDSL.create() { b =>
implicit val order = ByteOrder.LITTLE_ENDIAN implicit val order = ByteOrder.LITTLE_ENDIAN
def addLengthHeader(bytes: ByteString) = { def addLengthHeader(bytes: ByteString) = {
@ -116,12 +116,12 @@ object BidiFlowDocSpec {
}) })
//#framing //#framing
val chopUp = BidiFlow.fromGraph(FlowGraph.create() { b => val chopUp = BidiFlow.fromGraph(GraphDSL.create() { b =>
val f = Flow[ByteString].mapConcat(_.map(ByteString(_))) val f = Flow[ByteString].mapConcat(_.map(ByteString(_)))
BidiShape.fromFlows(b.add(f), b.add(f)) BidiShape.fromFlows(b.add(f), b.add(f))
}) })
val accumulate = BidiFlow.fromGraph(FlowGraph.create() { b => val accumulate = BidiFlow.fromGraph(GraphDSL.create() { b =>
val f = Flow[ByteString].grouped(1000).map(_.fold(ByteString.empty)(_ ++ _)) val f = Flow[ByteString].grouped(1000).map(_.fold(ByteString.empty)(_ ++ _))
BidiShape.fromFlows(b.add(f), b.add(f)) BidiShape.fromFlows(b.add(f), b.add(f))
}) })

View file

@ -76,8 +76,8 @@ class CompositionDocSpec extends AkkaSpec {
"complex graph" in { "complex graph" in {
// format: OFF // format: OFF
//#complex-graph //#complex-graph
import FlowGraph.Implicits._ import GraphDSL.Implicits._
RunnableGraph.fromGraph(FlowGraph.create() { implicit builder => RunnableGraph.fromGraph(GraphDSL.create() { implicit builder =>
val A: Outlet[Int] = builder.add(Source.single(0)).outlet val A: Outlet[Int] = builder.add(Source.single(0)).outlet
val B: UniformFanOutShape[Int, Int] = builder.add(Broadcast[Int](2)) val B: UniformFanOutShape[Int, Int] = builder.add(Broadcast[Int](2))
val C: UniformFanInShape[Int, Int] = builder.add(Merge[Int](2)) val C: UniformFanInShape[Int, Int] = builder.add(Merge[Int](2))
@ -96,8 +96,8 @@ class CompositionDocSpec extends AkkaSpec {
//#complex-graph //#complex-graph
//#complex-graph-alt //#complex-graph-alt
import FlowGraph.Implicits._ import GraphDSL.Implicits._
RunnableGraph.fromGraph(FlowGraph.create() { implicit builder => RunnableGraph.fromGraph(GraphDSL.create() { implicit builder =>
val B = builder.add(Broadcast[Int](2)) val B = builder.add(Broadcast[Int](2))
val C = builder.add(Merge[Int](2)) val C = builder.add(Merge[Int](2))
val E = builder.add(Balance[Int](2)) val E = builder.add(Balance[Int](2))
@ -117,8 +117,8 @@ class CompositionDocSpec extends AkkaSpec {
"partial graph" in { "partial graph" in {
// format: OFF // format: OFF
//#partial-graph //#partial-graph
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val partial = FlowGraph.create() { implicit builder => val partial = GraphDSL.create() { implicit builder =>
val B = builder.add(Broadcast[Int](2)) val B = builder.add(Broadcast[Int](2))
val C = builder.add(Merge[Int](2)) val C = builder.add(Merge[Int](2))
val E = builder.add(Balance[Int](2)) val E = builder.add(Balance[Int](2))
@ -143,7 +143,7 @@ class CompositionDocSpec extends AkkaSpec {
val flow = Flow.fromGraph(partial) val flow = Flow.fromGraph(partial)
// Simple way to create a graph backed Source // Simple way to create a graph backed Source
val source = Source.fromGraph( FlowGraph.create() { implicit builder => val source = Source.fromGraph( GraphDSL.create() { implicit builder =>
val merge = builder.add(Merge[Int](2)) val merge = builder.add(Merge[Int](2))
Source.single(0) ~> merge Source.single(0) ~> merge
Source(List(2, 3, 4)) ~> merge Source(List(2, 3, 4)) ~> merge
@ -167,7 +167,7 @@ class CompositionDocSpec extends AkkaSpec {
"closed graph" in { "closed graph" in {
//#embed-closed //#embed-closed
val closed1 = Source.single(0).to(Sink.foreach(println)) val closed1 = Source.single(0).to(Sink.foreach(println))
val closed2 = RunnableGraph.fromGraph(FlowGraph.create() { implicit builder => val closed2 = RunnableGraph.fromGraph(GraphDSL.create() { implicit builder =>
val embeddedClosed: ClosedShape = builder.add(closed1) val embeddedClosed: ClosedShape = builder.add(closed1)
// //
embeddedClosed embeddedClosed

View file

@ -148,9 +148,9 @@ class FlowDocSpec extends AkkaSpec {
"various ways of transforming materialized values" in { "various ways of transforming materialized values" in {
import scala.concurrent.duration._ import scala.concurrent.duration._
val throttler = Flow.fromGraph(FlowGraph.create(Source.tick(1.second, 1.second, "test")) { implicit builder => val throttler = Flow.fromGraph(GraphDSL.create(Source.tick(1.second, 1.second, "test")) { implicit builder =>
tickSource => tickSource =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val zip = builder.add(ZipWith[String, Int, Int](Keep.right)) val zip = builder.add(ZipWith[String, Int, Int](Keep.right))
tickSource ~> zip.in0 tickSource ~> zip.in0
FlowShape(zip.in1, zip.out) FlowShape(zip.in1, zip.out)
@ -211,9 +211,9 @@ class FlowDocSpec extends AkkaSpec {
// The result of r11 can be also achieved by using the Graph API // The result of r11 can be also achieved by using the Graph API
val r12: RunnableGraph[(Promise[Option[Int]], Cancellable, Future[Int])] = val r12: RunnableGraph[(Promise[Option[Int]], Cancellable, Future[Int])] =
RunnableGraph.fromGraph(FlowGraph.create(source, flow, sink)((_, _, _)) { implicit builder => RunnableGraph.fromGraph(GraphDSL.create(source, flow, sink)((_, _, _)) { implicit builder =>
(src, f, dst) => (src, f, dst) =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
src ~> f ~> dst src ~> f ~> dst
ClosedShape ClosedShape
}) })

View file

@ -21,8 +21,8 @@ class FlowGraphDocSpec extends AkkaSpec {
"build simple graph" in { "build simple graph" in {
//format: OFF //format: OFF
//#simple-flow-graph //#simple-flow-graph
val g = RunnableGraph.fromGraph(FlowGraph.create() { implicit builder: FlowGraph.Builder[Unit] => val g = RunnableGraph.fromGraph(GraphDSL.create() { implicit builder: GraphDSL.Builder[Unit] =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val in = Source(1 to 10) val in = Source(1 to 10)
val out = Sink.ignore val out = Sink.ignore
@ -46,8 +46,8 @@ class FlowGraphDocSpec extends AkkaSpec {
"flow connection errors" in { "flow connection errors" in {
intercept[IllegalArgumentException] { intercept[IllegalArgumentException] {
//#simple-graph //#simple-graph
RunnableGraph.fromGraph(FlowGraph.create() { implicit builder => RunnableGraph.fromGraph(GraphDSL.create() { implicit builder =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val source1 = Source(1 to 10) val source1 = Source(1 to 10)
val source2 = Source(1 to 10) val source2 = Source(1 to 10)
@ -74,9 +74,9 @@ class FlowGraphDocSpec extends AkkaSpec {
// format: OFF // format: OFF
val g = val g =
//#flow-graph-reusing-a-flow //#flow-graph-reusing-a-flow
RunnableGraph.fromGraph(FlowGraph.create(topHeadSink, bottomHeadSink)((_, _)) { implicit builder => RunnableGraph.fromGraph(GraphDSL.create(topHeadSink, bottomHeadSink)((_, _)) { implicit builder =>
(topHS, bottomHS) => (topHS, bottomHS) =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val broadcast = builder.add(Broadcast[Int](2)) val broadcast = builder.add(Broadcast[Int](2))
Source.single(1) ~> broadcast.in Source.single(1) ~> broadcast.in
@ -133,8 +133,8 @@ class FlowGraphDocSpec extends AkkaSpec {
worker: Flow[In, Out, Any], worker: Flow[In, Out, Any],
workerCount: Int): Graph[PriorityWorkerPoolShape[In, Out], Unit] = { workerCount: Int): Graph[PriorityWorkerPoolShape[In, Out], Unit] = {
FlowGraph.create() { implicit b GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val priorityMerge = b.add(MergePreferred[In](1)) val priorityMerge = b.add(MergePreferred[In](1))
val balance = b.add(Balance[In](workerCount)) val balance = b.add(Balance[In](workerCount))
@ -168,8 +168,8 @@ class FlowGraphDocSpec extends AkkaSpec {
val worker1 = Flow[String].map("step 1 " + _) val worker1 = Flow[String].map("step 1 " + _)
val worker2 = Flow[String].map("step 2 " + _) val worker2 = Flow[String].map("step 2 " + _)
RunnableGraph.fromGraph(FlowGraph.create() { implicit b => RunnableGraph.fromGraph(GraphDSL.create() { implicit b =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val priorityPool1 = b.add(PriorityWorkerPool(worker1, 4)) val priorityPool1 = b.add(PriorityWorkerPool(worker1, 4))
val priorityPool2 = b.add(PriorityWorkerPool(worker2, 2)) val priorityPool2 = b.add(PriorityWorkerPool(worker2, 2))
@ -203,8 +203,8 @@ class FlowGraphDocSpec extends AkkaSpec {
"access to materialized value" in { "access to materialized value" in {
//#flow-graph-matvalue //#flow-graph-matvalue
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val foldFlow: Flow[Int, Int, Future[Int]] = Flow.fromGraph(FlowGraph.create(Sink.fold[Int, Int](0)(_ + _)) { val foldFlow: Flow[Int, Int, Future[Int]] = Flow.fromGraph(GraphDSL.create(Sink.fold[Int, Int](0)(_ + _)) {
implicit builder implicit builder
fold fold
FlowShape(fold.inlet, builder.materializedValue.mapAsync(4)(identity).outlet) FlowShape(fold.inlet, builder.materializedValue.mapAsync(4)(identity).outlet)
@ -214,9 +214,9 @@ class FlowGraphDocSpec extends AkkaSpec {
Await.result(Source(1 to 10).via(foldFlow).runWith(Sink.head), 3.seconds) should ===(55) Await.result(Source(1 to 10).via(foldFlow).runWith(Sink.head), 3.seconds) should ===(55)
//#flow-graph-matvalue-cycle //#flow-graph-matvalue-cycle
import FlowGraph.Implicits._ import GraphDSL.Implicits._
// This cannot produce any value: // This cannot produce any value:
val cyclicFold: Source[Int, Future[Int]] = Source.fromGraph(FlowGraph.create(Sink.fold[Int, Int](0)(_ + _)) { val cyclicFold: Source[Int, Future[Int]] = Source.fromGraph(GraphDSL.create(Sink.fold[Int, Int](0)(_ + _)) {
implicit builder => implicit builder =>
fold => fold =>
// - Fold cannot complete until its upstream mapAsync completes // - Fold cannot complete until its upstream mapAsync completes

View file

@ -1,12 +1,12 @@
package docs.stream package docs.stream
import akka.stream.FlowShape import akka.stream.FlowShape
import akka.stream.scaladsl.{ FlowGraph, Merge, Balance, Source, Flow } import akka.stream.scaladsl.{ GraphDSL, Merge, Balance, Source, Flow }
import akka.stream.testkit.AkkaSpec import akka.stream.testkit.AkkaSpec
class FlowParallelismDocSpec extends AkkaSpec { class FlowParallelismDocSpec extends AkkaSpec {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
case class ScoopOfBatter() case class ScoopOfBatter()
case class HalfCookedPancake() case class HalfCookedPancake()
@ -38,7 +38,7 @@ class FlowParallelismDocSpec extends AkkaSpec {
val fryingPan: Flow[ScoopOfBatter, Pancake, Unit] = val fryingPan: Flow[ScoopOfBatter, Pancake, Unit] =
Flow[ScoopOfBatter].map { batter => Pancake() } Flow[ScoopOfBatter].map { batter => Pancake() }
val pancakeChef: Flow[ScoopOfBatter, Pancake, Unit] = Flow.fromGraph(FlowGraph.create() { implicit builder => val pancakeChef: Flow[ScoopOfBatter, Pancake, Unit] = Flow.fromGraph(GraphDSL.create() { implicit builder =>
val dispatchBatter = builder.add(Balance[ScoopOfBatter](2)) val dispatchBatter = builder.add(Balance[ScoopOfBatter](2))
val mergePancakes = builder.add(Merge[Pancake](2)) val mergePancakes = builder.add(Merge[Pancake](2))
@ -59,7 +59,7 @@ class FlowParallelismDocSpec extends AkkaSpec {
"Demonstrate parallelized pipelines" in { "Demonstrate parallelized pipelines" in {
//#parallel-pipeline //#parallel-pipeline
val pancakeChef: Flow[ScoopOfBatter, Pancake, Unit] = val pancakeChef: Flow[ScoopOfBatter, Pancake, Unit] =
Flow.fromGraph(FlowGraph.create() { implicit builder => Flow.fromGraph(GraphDSL.create() { implicit builder =>
val dispatchBatter = builder.add(Balance[ScoopOfBatter](2)) val dispatchBatter = builder.add(Balance[ScoopOfBatter](2))
val mergePancakes = builder.add(Merge[Pancake](2)) val mergePancakes = builder.add(Merge[Pancake](2))
@ -77,7 +77,7 @@ class FlowParallelismDocSpec extends AkkaSpec {
"Demonstrate pipelined parallel processing" in { "Demonstrate pipelined parallel processing" in {
//#pipelined-parallel //#pipelined-parallel
val pancakeChefs1: Flow[ScoopOfBatter, HalfCookedPancake, Unit] = val pancakeChefs1: Flow[ScoopOfBatter, HalfCookedPancake, Unit] =
Flow.fromGraph(FlowGraph.create() { implicit builder => Flow.fromGraph(GraphDSL.create() { implicit builder =>
val dispatchBatter = builder.add(Balance[ScoopOfBatter](2)) val dispatchBatter = builder.add(Balance[ScoopOfBatter](2))
val mergeHalfPancakes = builder.add(Merge[HalfCookedPancake](2)) val mergeHalfPancakes = builder.add(Merge[HalfCookedPancake](2))
@ -90,7 +90,7 @@ class FlowParallelismDocSpec extends AkkaSpec {
}) })
val pancakeChefs2: Flow[HalfCookedPancake, Pancake, Unit] = val pancakeChefs2: Flow[HalfCookedPancake, Pancake, Unit] =
Flow.fromGraph(FlowGraph.create() { implicit builder => Flow.fromGraph(GraphDSL.create() { implicit builder =>
val dispatchHalfPancakes = builder.add(Balance[HalfCookedPancake](2)) val dispatchHalfPancakes = builder.add(Balance[HalfCookedPancake](2))
val mergePancakes = builder.add(Merge[Pancake](2)) val mergePancakes = builder.add(Merge[Pancake](2))

View file

@ -16,8 +16,8 @@ class GraphCyclesSpec extends AkkaSpec {
// format: OFF // format: OFF
//#deadlocked //#deadlocked
// WARNING! The graph below deadlocks! // WARNING! The graph below deadlocks!
RunnableGraph.fromGraph(FlowGraph.create() { implicit b => RunnableGraph.fromGraph(GraphDSL.create() { implicit b =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val merge = b.add(Merge[Int](2)) val merge = b.add(Merge[Int](2))
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))
@ -34,8 +34,8 @@ class GraphCyclesSpec extends AkkaSpec {
// format: OFF // format: OFF
//#unfair //#unfair
// WARNING! The graph below stops consuming from "source" after a few steps // WARNING! The graph below stops consuming from "source" after a few steps
RunnableGraph.fromGraph(FlowGraph.create() { implicit b => RunnableGraph.fromGraph(GraphDSL.create() { implicit b =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val merge = b.add(MergePreferred[Int](1)) val merge = b.add(MergePreferred[Int](1))
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))
@ -51,8 +51,8 @@ class GraphCyclesSpec extends AkkaSpec {
"include a dropping cycle" in { "include a dropping cycle" in {
// format: OFF // format: OFF
//#dropping //#dropping
RunnableGraph.fromGraph(FlowGraph.create() { implicit b => RunnableGraph.fromGraph(GraphDSL.create() { implicit b =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val merge = b.add(Merge[Int](2)) val merge = b.add(Merge[Int](2))
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))
@ -69,8 +69,8 @@ class GraphCyclesSpec extends AkkaSpec {
// format: OFF // format: OFF
//#zipping-dead //#zipping-dead
// WARNING! The graph below never processes any elements // WARNING! The graph below never processes any elements
RunnableGraph.fromGraph(FlowGraph.create() { implicit b => RunnableGraph.fromGraph(GraphDSL.create() { implicit b =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val zip = b.add(ZipWith[Int, Int, Int]((left, right) => right)) val zip = b.add(ZipWith[Int, Int, Int]((left, right) => right))
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))
@ -87,8 +87,8 @@ class GraphCyclesSpec extends AkkaSpec {
"include a live zipping cycle" in { "include a live zipping cycle" in {
// format: OFF // format: OFF
//#zipping-live //#zipping-live
RunnableGraph.fromGraph(FlowGraph.create() { implicit b => RunnableGraph.fromGraph(GraphDSL.create() { implicit b =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val zip = b.add(ZipWith((left: Int, right: Int) => left)) val zip = b.add(ZipWith((left: Int, right: Int) => left))
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))

View file

@ -66,7 +66,7 @@ class GraphStageDocSpec extends AkkaSpec {
//#custom-source-example //#custom-source-example
//#simple-source-usage //#simple-source-usage
// A GraphStage is a proper Graph, just like what FlowGraph.create would return // A GraphStage is a proper Graph, just like what GraphDSL.create would return
val sourceGraph: Graph[SourceShape[Int], Unit] = new NumbersSource val sourceGraph: Graph[SourceShape[Int], Unit] = new NumbersSource
// Create a Source from the Graph to access the DSL // Create a Source from the Graph to access the DSL

View file

@ -39,8 +39,8 @@ class StreamBuffersRateSpec extends AkkaSpec {
import scala.concurrent.duration._ import scala.concurrent.duration._
case class Tick() case class Tick()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b => RunnableGraph.fromGraph(GraphDSL.create() { implicit b =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val zipper = b.add(ZipWith[Tick, Int, Int]((tick, count) => count)) val zipper = b.add(ZipWith[Tick, Int, Int]((tick, count) => count))

View file

@ -19,8 +19,8 @@ class StreamPartialFlowGraphDocSpec extends AkkaSpec {
"build with open ports" in { "build with open ports" in {
//#simple-partial-flow-graph //#simple-partial-flow-graph
val pickMaxOfThree = FlowGraph.create() { implicit b => val pickMaxOfThree = GraphDSL.create() { implicit b =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val zip1 = b.add(ZipWith[Int, Int, Int](math.max _)) val zip1 = b.add(ZipWith[Int, Int, Int](math.max _))
val zip2 = b.add(ZipWith[Int, Int, Int](math.max _)) val zip2 = b.add(ZipWith[Int, Int, Int](math.max _))
@ -31,9 +31,9 @@ class StreamPartialFlowGraphDocSpec extends AkkaSpec {
val resultSink = Sink.head[Int] val resultSink = Sink.head[Int]
val g = RunnableGraph.fromGraph(FlowGraph.create(resultSink) { implicit b => val g = RunnableGraph.fromGraph(GraphDSL.create(resultSink) { implicit b =>
sink => sink =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
// importing the partial graph will return its shape (inlets & outlets) // importing the partial graph will return its shape (inlets & outlets)
val pm3 = b.add(pickMaxOfThree) val pm3 = b.add(pickMaxOfThree)
@ -52,8 +52,8 @@ class StreamPartialFlowGraphDocSpec extends AkkaSpec {
"build source from partial flow graph" in { "build source from partial flow graph" in {
//#source-from-partial-flow-graph //#source-from-partial-flow-graph
val pairs = Source.fromGraph(FlowGraph.create() { implicit b => val pairs = Source.fromGraph(GraphDSL.create() { implicit b =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
// prepare graph elements // prepare graph elements
val zip = b.add(Zip[Int, Int]()) val zip = b.add(Zip[Int, Int]())
@ -75,8 +75,8 @@ class StreamPartialFlowGraphDocSpec extends AkkaSpec {
"build flow from partial flow graph" in { "build flow from partial flow graph" in {
//#flow-from-partial-flow-graph //#flow-from-partial-flow-graph
val pairUpWithToString = val pairUpWithToString =
Flow.fromGraph(FlowGraph.create() { implicit b => Flow.fromGraph(GraphDSL.create() { implicit b =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
// prepare graph elements // prepare graph elements
val broadcast = b.add(Broadcast[Int](2)) val broadcast = b.add(Broadcast[Int](2))

View file

@ -118,8 +118,8 @@ class TwitterStreamQuickstartDocSpec extends AkkaSpec {
// format: OFF // format: OFF
//#flow-graph-broadcast //#flow-graph-broadcast
val g = RunnableGraph.fromGraph(FlowGraph.create() { implicit b => val g = RunnableGraph.fromGraph(GraphDSL.create() { implicit b =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val bcast = b.add(Broadcast[Tweet](2)) val bcast = b.add(Broadcast[Tweet](2))
tweets ~> bcast.in tweets ~> bcast.in

View file

@ -27,7 +27,7 @@ class RecipeCollectingMetrics extends RecipeSpec {
// //#periodic-metrics-collection // //#periodic-metrics-collection
// val currentLoad = loadUpdates.transform(() => new HoldWithWait) // val currentLoad = loadUpdates.transform(() => new HoldWithWait)
// //
// val graph = FlowGraph { implicit builder => // val graph = GraphDSL { implicit builder =>
// import FlowGraphImplicits._ // import FlowGraphImplicits._
// val collector = ZipWith[Int, Tick, String]( // val collector = ZipWith[Int, Tick, String](
// (load: Int, tick: Tick) => s"current load is $load") // (load: Int, tick: Tick) => s"current load is $load")

View file

@ -24,9 +24,9 @@ class RecipeDroppyBroadcast extends RecipeSpec {
val mySink3 = Sink(sub3) val mySink3 = Sink(sub3)
//#droppy-bcast //#droppy-bcast
val graph = RunnableGraph.fromGraph(FlowGraph.create(mySink1, mySink2, mySink3)((_, _, _)) { implicit b => val graph = RunnableGraph.fromGraph(GraphDSL.create(mySink1, mySink2, mySink3)((_, _, _)) { implicit b =>
(sink1, sink2, sink3) => (sink1, sink2, sink3) =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val bcast = b.add(Broadcast[Int](3)) val bcast = b.add(Broadcast[Int](3))
myElements ~> bcast myElements ~> bcast

View file

@ -99,8 +99,8 @@ class RecipeGlobalRateLimit extends RecipeSpec {
val probe = TestSubscriber.manualProbe[String]() val probe = TestSubscriber.manualProbe[String]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b => RunnableGraph.fromGraph(GraphDSL.create() { implicit b =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val merge = b.add(Merge[String](2)) val merge = b.add(Merge[String](2))
source1 ~> merge ~> Sink(probe) source1 ~> merge ~> Sink(probe)
source2 ~> merge source2 ~> merge

View file

@ -18,8 +18,8 @@ class RecipeManualTrigger extends RecipeSpec {
val sink = Sink(sub) val sink = Sink(sub)
//#manually-triggered-stream //#manually-triggered-stream
val graph = RunnableGraph.fromGraph(FlowGraph.create() { implicit builder => val graph = RunnableGraph.fromGraph(GraphDSL.create() { implicit builder =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val zip = builder.add(Zip[Message, Trigger]()) val zip = builder.add(Zip[Message, Trigger]())
elements ~> zip.in0 elements ~> zip.in0
triggerSource ~> zip.in1 triggerSource ~> zip.in1
@ -57,8 +57,8 @@ class RecipeManualTrigger extends RecipeSpec {
val sink = Sink(sub) val sink = Sink(sub)
//#manually-triggered-stream-zipwith //#manually-triggered-stream-zipwith
val graph = RunnableGraph.fromGraph(FlowGraph.create() { implicit builder => val graph = RunnableGraph.fromGraph(GraphDSL.create() { implicit builder =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val zip = builder.add(ZipWith((msg: Message, trigger: Trigger) => msg)) val zip = builder.add(ZipWith((msg: Message, trigger: Trigger) => msg))
elements ~> zip.in0 elements ~> zip.in0

View file

@ -19,9 +19,9 @@ class RecipeWorkerPool extends RecipeSpec {
//#worker-pool //#worker-pool
def balancer[In, Out](worker: Flow[In, Out, Any], workerCount: Int): Flow[In, Out, Unit] = { def balancer[In, Out](worker: Flow[In, Out, Any], workerCount: Int): Flow[In, Out, Unit] = {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
Flow.fromGraph(FlowGraph.create() { implicit b => Flow.fromGraph(GraphDSL.create() { implicit b =>
val balancer = b.add(Balance[In](workerCount, waitForAllDownstreams = true)) val balancer = b.add(Balance[In](workerCount, waitForAllDownstreams = true))
val merge = b.add(Merge[Out](workerCount)) val merge = b.add(Merge[Out](workerCount))

View file

@ -72,8 +72,8 @@ class StreamTcpDocSpec extends AkkaSpec {
connections runForeach { connection => connections runForeach { connection =>
val serverLogic = Flow.fromGraph(FlowGraph.create() { implicit b => val serverLogic = Flow.fromGraph(GraphDSL.create() { implicit b =>
import FlowGraph.Implicits._ import GraphDSL.Implicits._
// server logic, parses incoming commands // server logic, parses incoming commands
val commandParser = new PushStage[String, String] { val commandParser = new PushStage[String, String] {

View file

@ -92,18 +92,20 @@ Should be replaced by
.. includecode:: code/docs/MigrationsScala.scala#bidiflow-wrap .. includecode:: code/docs/MigrationsScala.scala#bidiflow-wrap
FlowGraph builder methods have been renamed FlowGraph class and builder methods have been renamed
=========================================== ===========================================
Due to incorrect overlap with the :class:`Flow` concept we renamed the :class:`FlowGraph` class to :class:`GraphDSL`.
There is now only one graph creation method called ``create`` which is analogous to the old ``partial`` method. For There is now only one graph creation method called ``create`` which is analogous to the old ``partial`` method. For
closed graphs now it is explicitly required to return ``ClosedShape`` at the end of the builder block. closed graphs now it is explicitly required to return ``ClosedShape`` at the end of the builder block.
Update procedure Update procedure
---------------- ----------------
1. Replace all occurrences of ``FlowGraph.partial()`` or ``FlowGraph.closed()`` with ``FlowGraph.create()`` 1. Search and replace all occurrences of ``FlowGraph`` with ``GraphDSL``.
2. Add ``ClosedShape`` as a return value of the builder block if it was ``FlowGraph.closed()`` before 2. Replace all occurrences of ``GraphDSL.partial()`` or ``GraphDSL.closed()`` with ``GraphDSL.create()``.
3. Wrap the closed graph with ``RunnableGraph.fromGraph`` if it was ``FlowGraph.closed()`` before 3. Add ``ClosedShape`` as a return value of the builder block if it was ``FlowGraph.closed()`` before.
4. Wrap the closed graph with ``RunnableGraph.fromGraph`` if it was ``FlowGraph.closed()`` before.
Example Example
^^^^^^^ ^^^^^^^
@ -131,7 +133,7 @@ Methods that create Source, Sink, Flow from Graphs have been removed
Previously there were convenience methods available on ``Sink``, ``Source``, ``Flow`` an ``BidiFlow`` to create Previously there were convenience methods available on ``Sink``, ``Source``, ``Flow`` an ``BidiFlow`` to create
these DSL elements from a graph builder directly. Now this requires two explicit steps to reduce the number of overloaded these DSL elements from a graph builder directly. Now this requires two explicit steps to reduce the number of overloaded
methods (helps Java 8 type inference) and also reduces the ways how these elements can be created. There is only one methods (helps Java 8 type inference) and also reduces the ways how these elements can be created. There is only one
graph creation method to learn (``FlowGraph.create``) and then there is only one conversion method to use ``fromGraph()``. graph creation method to learn (``GraphDSL.create``) and then there is only one conversion method to use ``fromGraph()``.
This means that the following methods have been removed: This means that the following methods have been removed:
- ``adapt()`` method on ``Source``, ``Sink``, ``Flow`` and ``BidiFlow`` (both DSLs) - ``adapt()`` method on ``Source``, ``Sink``, ``Flow`` and ``BidiFlow`` (both DSLs)
@ -144,7 +146,7 @@ Update procedure
Everywhere where ``Source``, ``Sink``, ``Flow`` and ``BidiFlow`` is created from a graph using a builder have to Everywhere where ``Source``, ``Sink``, ``Flow`` and ``BidiFlow`` is created from a graph using a builder have to
be replaced with two steps be replaced with two steps
1. Create a ``Graph`` with the correct ``Shape`` using ``FlowGraph.create`` (e.g.. for ``Source`` it means first 1. Create a ``Graph`` with the correct ``Shape`` using ``GraphDSL.create`` (e.g.. for ``Source`` it means first
creating a ``Graph`` with ``SourceShape``) creating a ``Graph`` with ``SourceShape``)
2. Create the required DSL element by calling ``fromGraph()`` on the required DSL element (e.g. ``Source.fromGraph``) 2. Create the required DSL element by calling ``fromGraph()`` on the required DSL element (e.g. ``Source.fromGraph``)
passing the graph created in the previous step passing the graph created in the previous step
@ -187,7 +189,7 @@ Several Graph builder methods have been removed
The ``addEdge`` methods have been removed from the DSL to reduce the ways connections can be made and to reduce the The ``addEdge`` methods have been removed from the DSL to reduce the ways connections can be made and to reduce the
number of overloads. Now only the ``~>`` notation is available which requires the import of the implicits number of overloads. Now only the ``~>`` notation is available which requires the import of the implicits
``FlowGraph.Implicits._``. ``GraphDSL.Implicits._``.
Update procedure Update procedure
---------------- ----------------

View file

@ -126,7 +126,7 @@ As a first example, let's look at a more complex layout:
The diagram shows a :class:`RunnableGraph` (remember, if there are no unwired ports, the graph is closed, and therefore The diagram shows a :class:`RunnableGraph` (remember, if there are no unwired ports, the graph is closed, and therefore
can be materialized) that encapsulates a non-trivial stream processing network. It contains fan-in, fan-out stages, can be materialized) that encapsulates a non-trivial stream processing network. It contains fan-in, fan-out stages,
directed and non-directed cycles. The ``runnable()`` method of the :class:`FlowGraph` object allows the creation of a directed and non-directed cycles. The ``runnable()`` method of the :class:`GraphDSL` object allows the creation of a
general, closed, and runnable graph. For example the network on the diagram can be realized like this: general, closed, and runnable graph. For example the network on the diagram can be realized like this:
.. includecode:: code/docs/stream/CompositionDocSpec.scala#complex-graph .. includecode:: code/docs/stream/CompositionDocSpec.scala#complex-graph
@ -141,7 +141,7 @@ explicitly, and it is not necessary to import our linear stages via ``add()``, s
Similar to the case in the first section, so far we have not considered modularity. We created a complex graph, but Similar to the case in the first section, so far we have not considered modularity. We created a complex graph, but
the layout is flat, not modularized. We will modify our example, and create a reusable component with the graph DSL. the layout is flat, not modularized. We will modify our example, and create a reusable component with the graph DSL.
The way to do it is to use the ``create()`` factory method on :class:`FlowGraph`. If we remove the sources and sinks The way to do it is to use the ``create()`` factory method on :class:`GraphDSL`. If we remove the sources and sinks
from the previous example, what remains is a partial graph: from the previous example, what remains is a partial graph:
| |
@ -284,7 +284,7 @@ Attributes
---------- ----------
We have seen that we can use ``named()`` to introduce a nesting level in the fluid DSL (and also explicit nesting by using We have seen that we can use ``named()`` to introduce a nesting level in the fluid DSL (and also explicit nesting by using
``create()`` from :class:`FlowGraph`). Apart from having the effect of adding a nesting level, ``named()`` is actually ``create()`` from :class:`GraphDSL`). Apart from having the effect of adding a nesting level, ``named()`` is actually
a shorthand for calling ``withAttributes(Attributes.name("someName"))``. Attributes provide a way to fine-tune certain a shorthand for calling ``withAttributes(Attributes.name("someName"))``. Attributes provide a way to fine-tune certain
aspects of the materialized running entity. For example buffer sizes can be controlled via attributes (see aspects of the materialized running entity. For example buffer sizes can be controlled via attributes (see
:ref:`stream-buffers-scala`). When it comes to hierarchic composition, attributes are inherited by nested modules, :ref:`stream-buffers-scala`). When it comes to hierarchic composition, attributes are inherited by nested modules,

View file

@ -15,7 +15,7 @@ Custom processing with GraphStage
================================= =================================
The :class:`GraphStage` abstraction can be used to create arbitrary graph processing stages with any number of input The :class:`GraphStage` abstraction can be used to create arbitrary graph processing stages with any number of input
or output ports. It is a counterpart of the ``FlowGraph.create()`` method which creates new stream processing or output ports. It is a counterpart of the ``GraphDSL.create()`` method which creates new stream processing
stages by composing others. Where :class:`GraphStage` differs is that it creates a stage that is itself not divisible into stages by composing others. Where :class:`GraphStage` differs is that it creates a stage that is itself not divisible into
smaller ones, and allows state to be maintained inside it in a safe way. smaller ones, and allows state to be maintained inside it in a safe way.

View file

@ -31,8 +31,11 @@ Back-pressure
Non-Blocking Non-Blocking
Means that a certain operation does not hinder the progress of the calling thread, even if it takes long time to Means that a certain operation does not hinder the progress of the calling thread, even if it takes long time to
finish the requested operation. finish the requested operation.
Graph
A description of a stream processing topology, defining the pathways through which elements shall flow when the stream
is running.
Processing Stage Processing Stage
The common name for all building blocks that build up a Flow or FlowGraph. The common name for all building blocks that build up a Graph.
Examples of a processing stage would be operations like ``map()``, ``filter()``, stages added by ``transform()`` like Examples of a processing stage would be operations like ``map()``, ``filter()``, stages added by ``transform()`` like
:class:`PushStage`, :class:`PushPullStage`, :class:`StatefulStage` and graph junctions like ``Merge`` or ``Broadcast``. :class:`PushStage`, :class:`PushPullStage`, :class:`StatefulStage` and graph junctions like ``Merge`` or ``Broadcast``.
For the full list of built-in processing stages see :ref:`stages-overview` For the full list of built-in processing stages see :ref:`stages-overview`
@ -67,7 +70,7 @@ it will be represented by the ``RunnableGraph`` type, indicating that it is read
It is important to remember that even after constructing the ``RunnableGraph`` by connecting all the source, sink and It is important to remember that even after constructing the ``RunnableGraph`` by connecting all the source, sink and
different processing stages, no data will flow through it until it is materialized. Materialization is the process of different processing stages, no data will flow through it until it is materialized. Materialization is the process of
allocating all resources needed to run the computation described by a Flow (in Akka Streams this will often involve allocating all resources needed to run the computation described by a Graph (in Akka Streams this will often involve
starting up Actors). Thanks to Flows being simply a description of the processing pipeline they are *immutable, starting up Actors). Thanks to Flows being simply a description of the processing pipeline they are *immutable,
thread-safe, and freely shareable*, which means that it is for example safe to share and send them between actors, to have thread-safe, and freely shareable*, which means that it is for example safe to share and send them between actors, to have
one actor prepare the work, and then have it be materialized at some completely different place in the code. one actor prepare the work, and then have it be materialized at some completely different place in the code.
@ -204,11 +207,11 @@ Stream Materialization
When constructing flows and graphs in Akka Streams think of them as preparing a blueprint, an execution plan. When constructing flows and graphs in Akka Streams think of them as preparing a blueprint, an execution plan.
Stream materialization is the process of taking a stream description (the graph) and allocating all the necessary resources Stream materialization is the process of taking a stream description (the graph) and allocating all the necessary resources
it needs in order to run. In the case of Akka Streams this often means starting up Actors which power the processing, it needs in order to run. In the case of Akka Streams this often means starting up Actors which power the processing,
but is not restricted to that - it could also mean opening files or socket connections etc. depending on what the stream needs. but is not restricted to that—it could also mean opening files or socket connections etc.—depending on what the stream needs.
Materialization is triggered at so called "terminal operations". Most notably this includes the various forms of the ``run()`` Materialization is triggered at so called "terminal operations". Most notably this includes the various forms of the ``run()``
and ``runWith()`` methods defined on flow elements as well as a small number of special syntactic sugars for running with and ``runWith()`` methods defined on :class:`Source` and :class:`Flow` elements as well as a small number of special syntactic sugars for running with
well-known sinks, such as ``runForeach(el => )`` (being an alias to ``runWith(Sink.foreach(el => ))``. well-known sinks, such as ``runForeach(el => ...)`` (being an alias to ``runWith(Sink.foreach(el => ...))``.
Materialization is currently performed synchronously on the materializing thread. Materialization is currently performed synchronously on the materializing thread.
The actual stream processing is handled by actors started up during the streams materialization, The actual stream processing is handled by actors started up during the streams materialization,
@ -216,7 +219,7 @@ which will be running on the thread pools they have been configured to run on -
:class:`MaterializationSettings` while constructing the :class:`ActorMaterializer`. :class:`MaterializationSettings` while constructing the :class:`ActorMaterializer`.
.. note:: .. note::
Reusing *instances* of linear computation stages (Source, Sink, Flow) inside FlowGraphs is legal, Reusing *instances* of linear computation stages (Source, Sink, Flow) inside composite Graphs is legal,
yet will materialize that stage multiple times. yet will materialize that stage multiple times.
.. _flow-combine-mat-scala: .. _flow-combine-mat-scala:

View file

@ -17,10 +17,10 @@ streams, such that the second one is consumed after the first one has completed)
.. _flow-graph-scala: .. _flow-graph-scala:
Constructing Flow Graphs Constructing Graphs
------------------------ -------------------
Flow graphs are built from simple Flows which serve as the linear connections within the graphs as well as junctions Graphs are built from simple Flows which serve as the linear connections within the graphs as well as junctions
which serve as fan-in and fan-out points for Flows. Thanks to the junctions having meaningful types based on their behaviour which serve as fan-in and fan-out points for Flows. Thanks to the junctions having meaningful types based on their behaviour
and making them explicit elements these elements should be rather straightforward to use. and making them explicit elements these elements should be rather straightforward to use.
@ -41,7 +41,7 @@ Akka Streams currently provide these junctions (for a detailed list see :ref:`st
- ``Zip[A,B]`` *(2 inputs, 1 output)* is a :class:`ZipWith` specialised to zipping input streams of ``A`` and ``B`` into an ``(A,B)`` tuple stream - ``Zip[A,B]`` *(2 inputs, 1 output)* is a :class:`ZipWith` specialised to zipping input streams of ``A`` and ``B`` into an ``(A,B)`` tuple stream
- ``Concat[A]`` *(2 inputs, 1 output)* concatenates two streams (first consume one, then the second one) - ``Concat[A]`` *(2 inputs, 1 output)* concatenates two streams (first consume one, then the second one)
One of the goals of the FlowGraph DSL is to look similar to how one would draw a graph on a whiteboard, so that it is One of the goals of the GraphDSL DSL is to look similar to how one would draw a graph on a whiteboard, so that it is
simple to translate a design from whiteboard to code and be able to relate those two. Let's illustrate this by translating simple to translate a design from whiteboard to code and be able to relate those two. Let's illustrate this by translating
the below hand drawn graph into Akka Streams: the below hand drawn graph into Akka Streams:
@ -55,18 +55,18 @@ will be inferred.
.. includecode:: code/docs/stream/FlowGraphDocSpec.scala#simple-flow-graph .. includecode:: code/docs/stream/FlowGraphDocSpec.scala#simple-flow-graph
.. note:: .. note::
Junction *reference equality* defines *graph node equality* (i.e. the same merge *instance* used in a FlowGraph Junction *reference equality* defines *graph node equality* (i.e. the same merge *instance* used in a GraphDSL
refers to the same location in the resulting graph). refers to the same location in the resulting graph).
Notice the ``import FlowGraph.Implicits._`` which brings into scope the ``~>`` operator (read as "edge", "via" or "to") Notice the ``import GraphDSL.Implicits._`` which brings into scope the ``~>`` operator (read as "edge", "via" or "to")
and its inverted counterpart ``<~`` (for noting down flows in the opposite direction where appropriate). and its inverted counterpart ``<~`` (for noting down flows in the opposite direction where appropriate).
By looking at the snippets above, it should be apparent that the :class:`FlowGraph.Builder` object is *mutable*. By looking at the snippets above, it should be apparent that the :class:`GraphDSL.Builder` object is *mutable*.
It is used (implicitly) by the ``~>`` operator, also making it a mutable operation as well. It is used (implicitly) by the ``~>`` operator, also making it a mutable operation as well.
The reason for this design choice is to enable simpler creation of complex graphs, which may even contain cycles. The reason for this design choice is to enable simpler creation of complex graphs, which may even contain cycles.
Once the FlowGraph has been constructed though, the :class:`FlowGraph` instance *is immutable, thread-safe, and freely shareable*. Once the GraphDSL has been constructed though, the :class:`GraphDSL` instance *is immutable, thread-safe, and freely shareable*.
The same is true of all flow pieces—sources, sinks, and flows—once they are constructed. The same is true of all graph pieces—sources, sinks, and flows—once they are constructed.
This means that you can safely re-use one given Flow in multiple places in a processing graph. This means that you can safely re-use one given Flow or junction in multiple places in a processing graph.
We have seen examples of such re-use already above: the merge and broadcast junctions were imported We have seen examples of such re-use already above: the merge and broadcast junctions were imported
into the graph using ``builder.add(...)``, an operation that will make a copy of the blueprint that into the graph using ``builder.add(...)``, an operation that will make a copy of the blueprint that
@ -84,18 +84,18 @@ materialized as two connections between the corresponding Sources and Sinks:
.. _partial-flow-graph-scala: .. _partial-flow-graph-scala:
Constructing and combining Partial Flow Graphs Constructing and combining Partial Graphs
---------------------------------------------- -----------------------------------------
Sometimes it is not possible (or needed) to construct the entire computation graph in one place, but instead construct Sometimes it is not possible (or needed) to construct the entire computation graph in one place, but instead construct
all of its different phases in different places and in the end connect them all into a complete graph and run it. all of its different phases in different places and in the end connect them all into a complete graph and run it.
This can be achieved by returning a different ``Shape`` than ``ClosedShape``, for example ``FlowShape(in, out)``, from the This can be achieved by returning a different ``Shape`` than ``ClosedShape``, for example ``FlowShape(in, out)``, from the
function given to ``FlowGraph.create``. See :ref:`predefined_shapes`) for a list of such predefined shapes. function given to ``GraphDSL.create``. See :ref:`predefined_shapes`) for a list of such predefined shapes.
Making a ``Graph`` a :class:`RunnableGraph` requires all ports to be connected, and if they are not Making a ``Graph`` a :class:`RunnableGraph` requires all ports to be connected, and if they are not
it will throw an exception at construction time, which helps to avoid simple it will throw an exception at construction time, which helps to avoid simple
wiring errors while working with graphs. A partial flow graph however allows wiring errors while working with graphs. A partial graph however allows
you to return the set of yet to be connected ports from the code block that you to return the set of yet to be connected ports from the code block that
performs the internal wiring. performs the internal wiring.
@ -112,10 +112,10 @@ the undefined elements are rewired to real sources and sinks. The graph can then
.. warning:: .. warning::
Please note that :class:`FlowGraph` is not able to provide compile time type-safety about whether or not all Please note that :class:`GraphDSL` is not able to provide compile time type-safety about whether or not all
elements have been properly connected—this validation is performed as a runtime check during the graph's instantiation. elements have been properly connected—this validation is performed as a runtime check during the graph's instantiation.
A partial flow graph also verifies that all ports are either connected or part of the returned :class:`Shape`. A partial graph also verifies that all ports are either connected or part of the returned :class:`Shape`.
.. _constructing-sources-sinks-flows-from-partial-graphs-scala: .. _constructing-sources-sinks-flows-from-partial-graphs-scala:
@ -136,7 +136,7 @@ Being able to hide complex graphs inside of simple elements such as Sink / Sourc
complex element and from there on treat it as simple compound stage for linear computations. complex element and from there on treat it as simple compound stage for linear computations.
In order to create a Source from a graph the method ``Source.fromGraph`` is used, to use it we must have a In order to create a Source from a graph the method ``Source.fromGraph`` is used, to use it we must have a
``Graph[SourceShape, T]``. This is constructed using ``FlowGraph.create`` and returning a ``SourceShape`` ``Graph[SourceShape, T]``. This is constructed using ``GraphDSL.create`` and returning a ``SourceShape``
from the function passed in . The single outlet must be provided to the ``SourceShape.of`` method and will become from the function passed in . The single outlet must be provided to the ``SourceShape.of`` method and will become
“the sink that must be attached before this Source can run”. “the sink that must be attached before this Source can run”.
@ -283,7 +283,7 @@ The following example demonstrates a case where the materialized ``Future`` of a
Graph cycles, liveness and deadlocks Graph cycles, liveness and deadlocks
------------------------------------ ------------------------------------
Cycles in bounded flow graphs need special considerations to avoid potential deadlocks and other liveness issues. Cycles in bounded stream topologies need special considerations to avoid potential deadlocks and other liveness issues.
This section shows several examples of problems that can arise from the presence of feedback arcs in stream processing This section shows several examples of problems that can arise from the presence of feedback arcs in stream processing
graphs. graphs.

View file

@ -86,10 +86,10 @@ it makes sense to make the Server initiate the conversation by emitting a "hello
.. includecode:: code/docs/stream/io/StreamTcpDocSpec.scala#welcome-banner-chat-server .. includecode:: code/docs/stream/io/StreamTcpDocSpec.scala#welcome-banner-chat-server
The way we constructed a :class:`Flow` using a :class:`PartialFlowGraph` is explained in detail in The way we constructed a :class:`Flow` using the :class:`GraphDSL` is explained in detail in
:ref:`constructing-sources-sinks-flows-from-partial-graphs-scala`, however the basic concepts is rather simple :ref:`constructing-sources-sinks-flows-from-partial-graphs-scala`, however the basic concepts is rather simple
we can encapsulate arbitrarily complex logic within a :class:`Flow` as long as it exposes the same interface, which means we can encapsulate arbitrarily complex logic within a :class:`Flow` as long as it exposes the same interface, which means
exposing exactly one :class:`UndefinedSink` and exactly one :class:`UndefinedSource` which will be connected to the TCP exposing exactly one :class:`Outlet` and exactly one :class:`Inlet` which will be connected to the TCP
pipeline. In this example we use a :class:`Concat` graph processing stage to inject the initial message, and then pipeline. In this example we use a :class:`Concat` graph processing stage to inject the initial message, and then
continue with handling all incoming data using the echo handler. You should use this pattern of encapsulating complex continue with handling all incoming data using the echo handler. You should use this pattern of encapsulating complex
logic in Flows and attaching those to :class:`StreamIO` in order to implement your custom and possibly sophisticated TCP servers. logic in Flows and attaching those to :class:`StreamIO` in order to implement your custom and possibly sophisticated TCP servers.

View file

@ -103,15 +103,15 @@ Akka Streams intentionally separate the linear stream structures (Flows) from th
in order to offer the most convenient API for both of these cases. Graphs can express arbitrarily complex stream setups in order to offer the most convenient API for both of these cases. Graphs can express arbitrarily complex stream setups
at the expense of not reading as familiarly as collection transformations. at the expense of not reading as familiarly as collection transformations.
Graphs are constructed using :class:`FlowGraph` like this: Graphs are constructed using :class:`GraphDSL` like this:
.. includecode:: code/docs/stream/TwitterStreamQuickstartDocSpec.scala#flow-graph-broadcast .. includecode:: code/docs/stream/TwitterStreamQuickstartDocSpec.scala#flow-graph-broadcast
As you can see, inside the :class:`FlowGraph` we use an implicit graph builder ``b`` to mutably construct the graph As you can see, inside the :class:`GraphDSL` we use an implicit graph builder ``b`` to mutably construct the graph
using the ``~>`` "edge operator" (also read as "connect" or "via" or "to"). The operator is provided implicitly using the ``~>`` "edge operator" (also read as "connect" or "via" or "to"). The operator is provided implicitly
by importing ``FlowGraph.Implicits._``. by importing ``GraphDSL.Implicits._``.
``FlowGraph.create`` returns a :class:`Graph`, in this example a :class:`Graph[ClosedShape, Unit]` where ``GraphDSL.create`` returns a :class:`Graph`, in this example a :class:`Graph[ClosedShape, Unit]` where
:class:`ClosedShape` means that it is *a fully connected graph* or "closed" - there are no unconnected inputs or outputs. :class:`ClosedShape` means that it is *a fully connected graph* or "closed" - there are no unconnected inputs or outputs.
Since it is closed it is possible to transform the graph into a :class:`RunnableGraph` using ``RunnableGraph.fromGraph``. Since it is closed it is possible to transform the graph into a :class:`RunnableGraph` using ``RunnableGraph.fromGraph``.
The runnable graph can then be ``run()`` to materialize a stream out of it. The runnable graph can then be ``run()`` to materialize a stream out of it.

View file

@ -75,7 +75,7 @@ Here is an example of a code that demonstrate some of the issues caused by inter
.. includecode:: code/docs/stream/StreamBuffersRateSpec.scala#buffering-abstraction-leak .. includecode:: code/docs/stream/StreamBuffersRateSpec.scala#buffering-abstraction-leak
Running the above example one would expect the number *3* to be printed in every 3 seconds (the ``conflate`` step here Running the above example one would expect the number *3* to be printed in every 3 seconds (the ``cUndefinedSourceonflate`` step here
is configured so that it counts the number of elements received before the downstream ``ZipWith`` consumes them). What is configured so that it counts the number of elements received before the downstream ``ZipWith`` consumes them). What
is being printed is different though, we will see the number *1*. The reason for this is the internal buffer which is is being printed is different though, we will see the number *1*. The reason for this is the internal buffer which is
by default 16 elements large, and prefetches elements before the ``ZipWith`` starts consuming them. It is possible by default 16 elements large, and prefetches elements before the ``ZipWith`` starts consuming them. It is possible
@ -141,15 +141,15 @@ Rate transformation
Understanding conflate Understanding conflate
---------------------- ----------------------
When a fast producer can not be informed to slow down by backpressure or some other signal, conflate might be useful to combine elements from a producer until a demand signal comes from a consumer. When a fast producer can not be informed to slow down by backpressure or some other signal, ``conflate`` might be useful to combine elements from a producer until a demand signal comes from a consumer.
Below is an example snippet that summarizes fast stream of elements to a standart deviation, mean and count of elements that have arrived while the stats have been calculated. Below is an example snippet that summarizes fast stream of elements to a standart deviation, mean and count of elements that have arrived while the stats have been calculated.
.. includecode:: code/docs/stream/RateTransformationDocSpec.scala#conflate-summarize .. includecode:: code/docs/stream/RateTransformationDocSpec.scala#conflate-summarize
This example demonstrates that such flow's rate is decoupled. Element rate at the start of the flow can be much higher that the element rate at the end of the flow. This example demonstrates that such flow's rate is decoupled. The element rate at the start of the flow can be much higher that the element rate at the end of the flow.
Another possible use of conflate is to not consider all elements for summary when producer starts getting too fast. Example below demonstrates how conflate can be used to implement random drop of elements when consumer is not able to keep up with the producer. Another possible use of ``conflate`` is to not consider all elements for summary when producer starts getting too fast. Example below demonstrates how ``conflate`` can be used to implement random drop of elements when consumer is not able to keep up with the producer.
.. includecode:: code/docs/stream/RateTransformationDocSpec.scala#conflate-sample .. includecode:: code/docs/stream/RateTransformationDocSpec.scala#conflate-sample
@ -158,7 +158,7 @@ Understanding expand
Expand helps to deal with slow producers which are unable to keep up with the demand coming from consumers. Expand allows to extrapolate a value to be sent as an element to a consumer. Expand helps to deal with slow producers which are unable to keep up with the demand coming from consumers. Expand allows to extrapolate a value to be sent as an element to a consumer.
As a simple use of expand here is a flow that sends the same element to consumer when producer does not send any new elements. As a simple use of ``expand`` here is a flow that sends the same element to consumer when producer does not send any new elements.
.. includecode:: code/docs/stream/RateTransformationDocSpec.scala#expand-last .. includecode:: code/docs/stream/RateTransformationDocSpec.scala#expand-last
@ -166,4 +166,4 @@ Expand also allows to keep some state between demand requests from the downstrea
.. includecode:: code/docs/stream/RateTransformationDocSpec.scala#expand-drift .. includecode:: code/docs/stream/RateTransformationDocSpec.scala#expand-drift
Note that all of the elements coming from upstream will go through expand at least once. This means that the output of this flow is going to report a drift of zero if producer is fast enough, or a larger drift otherwise. Note that all of the elements coming from upstream will go through ``expand`` at least once. This means that the output of this flow is going to report a drift of zero if producer is fast enough, or a larger drift otherwise.

View file

@ -25,30 +25,28 @@ This means that we provide all the tools necessary to express any stream process
Resulting Implementation Constraints Resulting Implementation Constraints
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Compositionality entails reusability of partial stream topologies, which led us to the lifted approach of describing data flows as (partial) FlowGraphs that can act as composite sources, flows (a.k.a. pipes) and sinks of data. These building blocks shall then be freely shareable, with the ability to combine them freely to form larger flows. The representation of these pieces must therefore be an immutable blueprint that is materialized in an explicit step in order to start the stream processing. The resulting stream processing engine is then also immutable in the sense of having a fixed topology that is prescribed by the blueprint. Dynamic networks need to be modeled by explicitly using the Reactive Streams interfaces for plugging different engines together. Compositionality entails reusability of partial stream topologies, which led us to the lifted approach of describing data flows as (partial) graphs that can act as composite sources, flows (a.k.a. pipes) and sinks of data. These building blocks shall then be freely shareable, with the ability to combine them freely to form larger graphs. The representation of these pieces must therefore be an immutable blueprint that is materialized in an explicit step in order to start the stream processing. The resulting stream processing engine is then also immutable in the sense of having a fixed topology that is prescribed by the blueprint. Dynamic networks need to be modeled by explicitly using the Reactive Streams interfaces for plugging different engines together.
The process of materialization may be parameterized, e.g. instantiating a blueprint for handling a TCP connections data with specific information about the connections address and port information. Additionally, materialization will often create specific objects that are useful to interact with the processing engine once it is running, for example for shutting it down or for extracting metrics. This means that the materialization function takes a set of parameters from the outside and it produces a set of results. Compositionality demands that these two sets cannot interact, because that would establish a covert channel by which different pieces could communicate, leading to problems of initialization order and inscrutable runtime failures. The process of materialization will often create specific objects that are useful to interact with the processing engine once it is running, for example for shutting it down or for extracting metrics. This means that the materialization function produces a result termed the *materialized value of a graph*.
Another aspect of materialization is that we want to support distributed stream processing, meaning that both the parameters and the results need to be location transparent—either serializable immutable values or ActorRefs. Using for example Futures would restrict materialization to the local JVM. There may be cases for which this will typically not be a severe restriction (like opening a TCP connection), but the principle remains.
Interoperation with other Reactive Streams implementations Interoperation with other Reactive Streams implementations
---------------------------------------------------------- ----------------------------------------------------------
Akka Streams fully implement the Reactive Streams specification and interoperate with all other conformant implementations. We chose to completely separate the Reactive Streams interfaces (which we regard to be an SPI) from the user-level API. In order to obtain a :class:`Publisher` or :class:`Subscriber` from an Akka Stream topology, a corresponding ``Sink.publisher`` or ``Source.subscriber`` element must be used. Akka Streams fully implement the Reactive Streams specification and interoperate with all other conformant implementations. We chose to completely separate the Reactive Streams interfaces from the user-level API because we regard them to be an SPI that is not targeted at endusers. In order to obtain a :class:`Publisher` or :class:`Subscriber` from an Akka Stream topology, a corresponding ``Sink.publisher`` or ``Source.subscriber`` element must be used.
All stream Processors produced by the default materialization of Akka Streams are restricted to having a single Subscriber, additional Subscribers will be rejected. The reason for this is that the stream topologies described using our DSL never require fan-out behavior from the Publisher sides of the elements, all fan-out is done using explicit elements like :class:`Broadcast[T]`. All stream Processors produced by the default materialization of Akka Streams are restricted to having a single Subscriber, additional Subscribers will be rejected. The reason for this is that the stream topologies described using our DSL never require fan-out behavior from the Publisher sides of the elements, all fan-out is done using explicit elements like :class:`Broadcast[T]`.
This means that ``Sink.publisher(true)`` must be used where broadcast behavior is needed for interoperation with other Reactive Streams implementations. This means that ``Sink.publisher(true)`` (for enabling fan-out support) must be used where broadcast behavior is needed for interoperation with other Reactive Streams implementations.
What shall users of streaming libraries expect? What shall users of streaming libraries expect?
----------------------------------------------- -----------------------------------------------
We expect libraries to be built on top of Akka Streams, in fact Akka HTTP is one such example that lives within the Akka project itself. In order to allow users to profit from the principles that are described for Akka Streams above, the following rules are established: We expect libraries to be built on top of Akka Streams, in fact Akka HTTP is one such example that lives within the Akka project itself. In order to allow users to profit from the principles that are described for Akka Streams above, the following rules are established:
* libraries shall provide their users with reusable pieces, allowing full compositionality * libraries shall provide their users with reusable pieces, i.e. expose factories that return graphs, allowing full compositionality
* libraries may optionally and additionally provide facilities that consume and materialize flow descriptions * libraries may optionally and additionally provide facilities that consume and materialize graphs
The reasoning behind the first rule is that compositionality would be destroyed if different libraries only accepted flow descriptions and expected to materialize them: using two of these together would be impossible because materialization can only happen once. As a consequence, the functionality of a library must be expressed such that materialization can be done by the user, outside of the librarys control. The reasoning behind the first rule is that compositionality would be destroyed if different libraries only accepted graphs and expected to materialize them: using two of these together would be impossible because materialization can only happen once. As a consequence, the functionality of a library must be expressed such that materialization can be done by the user, outside of the librarys control.
The second rule allows a library to additionally provide nice sugar for the common case, an example of which is the Akka HTTP API that provides a ``handleWith`` method for convenient materialization. The second rule allows a library to additionally provide nice sugar for the common case, an example of which is the Akka HTTP API that provides a ``handleWith`` method for convenient materialization.
@ -56,6 +54,8 @@ The second rule allows a library to additionally provide nice sugar for the comm
One important consequence of this is that a reusable flow description cannot be bound to “live” resources, any connection to or allocation of such resources must be deferred until materialization time. Examples of “live” resources are already existing TCP connections, a multicast Publisher, etc.; a TickSource does not fall into this category if its timer is created only upon materialization (as is the case for our implementation). One important consequence of this is that a reusable flow description cannot be bound to “live” resources, any connection to or allocation of such resources must be deferred until materialization time. Examples of “live” resources are already existing TCP connections, a multicast Publisher, etc.; a TickSource does not fall into this category if its timer is created only upon materialization (as is the case for our implementation).
Exceptions from this need to be well-justified and carefully documented.
Resulting Implementation Constraints Resulting Implementation Constraints
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -64,7 +64,7 @@ Akka Streams must enable a library to express any stream processing utility in t
* Source: something with exactly one output stream * Source: something with exactly one output stream
* Sink: something with exactly one input stream * Sink: something with exactly one input stream
* Flow: something with exactly one input and one output stream * Flow: something with exactly one input and one output stream
* BidirectionalFlow: something with exactly two input streams and two output streams that conceptually behave like two Flows of opposite direction * BidiFlow: something with exactly two input streams and two output streams that conceptually behave like two Flows of opposite direction
* Graph: a packaged stream processing topology that exposes a certain set of input and output ports, characterized by an object of type :class:`Shape`. * Graph: a packaged stream processing topology that exposes a certain set of input and output ports, characterized by an object of type :class:`Shape`.
.. note:: .. note::
@ -87,23 +87,6 @@ The ability for failures to propagate faster than data elements is essential for
The semantics of stream recovery The semantics of stream recovery
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A recovery element (i.e. any transformation that absorbs an ``onError`` signal and turns that into possibly more data elements followed normal stream completion) acts as a bulkhead that confines a stream collapse to a given region of the flow topology. Within the collapsed region buffered elements may be lost, but the outside is not affected by the failure. A recovery element (i.e. any transformation that absorbs an ``onError`` signal and turns that into possibly more data elements followed normal stream completion) acts as a bulkhead that confines a stream collapse to a given region of the stream topology. Within the collapsed region buffered elements may be lost, but the outside is not affected by the failure.
This works in the same fashion as a ``try````catch`` expression: it marks a region in which exceptions are caught, but the exact amount of code that was skipped within this region in case of a failure might not be known precisely—the placement of statements matters. This works in the same fashion as a ``try````catch`` expression: it marks a region in which exceptions are caught, but the exact amount of code that was skipped within this region in case of a failure might not be known precisely—the placement of statements matters.
The finer points of stream materialization
------------------------------------------
.. note::
This is not yet implemented as stated here, this document illustrates intent.
It is commonly necessary to parameterize a flow so that it can be materialized for different arguments, an example would be the handler Flow that is given to a server socket implementation and materialized for each incoming connection with information about the peers address. On the other hand it is frequently necessary to retrieve specific objects that result from materialization, for example a ``Future[Unit]`` that signals the completion of a ``ForeachSink``.
It might be tempting to allow different pieces of a flow topology to access the materialization results of other pieces in order to customize their behavior, but that would violate composability and reusability as argued above. Therefore the arguments and results of materialization need to be segregated:
* The Materializer is configured with a (type-safe) mapping from keys to values, which is exposed to the processing stages during their materialization.
* The values in this mapping may act as channels, for example by using a Promise/Future pair to communicate a value; another possibility for such information-passing is of course to explicitly model it as a stream of configuration data elements within the graph itself.
* The materialized values obtained from the processing stages are combined as prescribed by the user, but can of course be dependent on the values in the argument mapping.
To avoid having to use ``Future`` values as key bindings, materialization itself may become fully asynchronous. This would allow for example the use of the bound server port within the rest of the flow, and only if the port was actually bound successfully. The downside is that some APIs will then return ``Future[MaterializedMap]``, which means that others will have to accept this in turn in order to keep the usage burden as low as possible.

View file

@ -76,8 +76,8 @@ private[http] object OutgoingConnectionBlueprint {
case (MessageStartError(_, info), _) throw IllegalResponseException(info) case (MessageStartError(_, info), _) throw IllegalResponseException(info)
} }
val core = BidiFlow.fromGraph(FlowGraph.create() { implicit b val core = BidiFlow.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val methodBypassFanout = b.add(Broadcast[HttpRequest](2, eagerCancel = true)) val methodBypassFanout = b.add(Broadcast[HttpRequest](2, eagerCancel = true))
val responseParsingMerge = b.add(new ResponseParsingMerge(rootParser)) val responseParsingMerge = b.add(new ResponseParsingMerge(rootParser))

View file

@ -65,8 +65,8 @@ private object PoolConductor {
*/ */
def apply(slotCount: Int, pipeliningLimit: Int, log: LoggingAdapter): Graph[Ports, Any] = def apply(slotCount: Int, pipeliningLimit: Int, log: LoggingAdapter): Graph[Ports, Any] =
FlowGraph.create() { implicit b GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val retryMerge = b.add(MergePreferred[RequestContext](1, eagerClose = true)) val retryMerge = b.add(MergePreferred[RequestContext](1, eagerClose = true))
val slotSelector = b.add(new SlotSelector(slotCount, pipeliningLimit, log)) val slotSelector = b.add(new SlotSelector(slotCount, pipeliningLimit, log))

View file

@ -70,9 +70,9 @@ private object PoolFlow {
def apply(connectionFlow: Flow[HttpRequest, HttpResponse, Future[Http.OutgoingConnection]], def apply(connectionFlow: Flow[HttpRequest, HttpResponse, Future[Http.OutgoingConnection]],
remoteAddress: InetSocketAddress, settings: ConnectionPoolSettings, log: LoggingAdapter)( remoteAddress: InetSocketAddress, settings: ConnectionPoolSettings, log: LoggingAdapter)(
implicit system: ActorSystem, fm: Materializer): Flow[RequestContext, ResponseContext, Unit] = implicit system: ActorSystem, fm: Materializer): Flow[RequestContext, ResponseContext, Unit] =
Flow.fromGraph(FlowGraph.create[FlowShape[RequestContext, ResponseContext]]() { implicit b Flow.fromGraph(GraphDSL.create[FlowShape[RequestContext, ResponseContext]]() { implicit b
import settings._ import settings._
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val conductor = b.add(PoolConductor(maxConnections, pipeliningLimit, log)) val conductor = b.add(PoolConductor(maxConnections, pipeliningLimit, log))
val slots = Vector val slots = Vector

View file

@ -55,8 +55,8 @@ private object PoolSlot {
remoteAddress: InetSocketAddress, // TODO: remove after #16168 is cleared remoteAddress: InetSocketAddress, // TODO: remove after #16168 is cleared
settings: ConnectionPoolSettings)(implicit system: ActorSystem, settings: ConnectionPoolSettings)(implicit system: ActorSystem,
fm: Materializer): Graph[FanOutShape2[RequestContext, ResponseContext, RawSlotEvent], Any] = fm: Materializer): Graph[FanOutShape2[RequestContext, ResponseContext, RawSlotEvent], Any] =
FlowGraph.create() { implicit b GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
// TODO wouldn't be better to have them under a known parent? /user/SlotProcessor-0 seems weird // TODO wouldn't be better to have them under a known parent? /user/SlotProcessor-0 seems weird
val name = slotProcessorActorName.next() val name = slotProcessorActorName.next()

View file

@ -32,9 +32,9 @@ private object RenderSupport {
val defaultLastChunkBytes: ByteString = renderChunk(HttpEntity.LastChunk) val defaultLastChunkBytes: ByteString = renderChunk(HttpEntity.LastChunk)
def CancelSecond[T, Mat](first: Source[T, Mat], second: Source[T, Any]): Source[T, Mat] = { def CancelSecond[T, Mat](first: Source[T, Mat], second: Source[T, Any]): Source[T, Mat] = {
Source.fromGraph(FlowGraph.create(first) { implicit b Source.fromGraph(GraphDSL.create(first) { implicit b
frst frst
import FlowGraph.Implicits._ import GraphDSL.Implicits._
second ~> Sink.cancelled second ~> Sink.cancelled
SourceShape(frst.outlet) SourceShape(frst.outlet)
}) })

View file

@ -66,8 +66,8 @@ private[http] object HttpServerBluePrint {
def websocketSupport(settings: ServerSettings, log: LoggingAdapter)(implicit mat: Materializer): BidiFlow[ResponseRenderingOutput, ByteString, ByteString, ByteString, Unit] = { def websocketSupport(settings: ServerSettings, log: LoggingAdapter)(implicit mat: Materializer): BidiFlow[ResponseRenderingOutput, ByteString, ByteString, ByteString, Unit] = {
val ws = websocketSetup val ws = websocketSetup
BidiFlow.fromGraph(FlowGraph.create() { implicit b BidiFlow.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val switch = b.add(new ProtocolSwitchStage(ws.installHandler, settings.websocketRandomFactory, log)) val switch = b.add(new ProtocolSwitchStage(ws.installHandler, settings.websocketRandomFactory, log))

View file

@ -121,8 +121,8 @@ private[http] object Websocket {
MessageToFrameRenderer.create(serverSide) MessageToFrameRenderer.create(serverSide)
.named("ws-render-messages") .named("ws-render-messages")
BidiFlow.fromGraph(FlowGraph.create() { implicit b BidiFlow.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val split = b.add(BypassRouter) val split = b.add(BypassRouter)
val tick = Source.tick(closeTimeout, closeTimeout, Tick) val tick = Source.tick(closeTimeout, closeTimeout, Tick)

View file

@ -109,8 +109,8 @@ object WebsocketClientBlueprint {
} }
} }
BidiFlow.fromGraph(FlowGraph.create() { implicit b BidiFlow.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val networkIn = b.add(Flow[ByteString].transform(() new UpgradeStage)) val networkIn = b.add(Flow[ByteString].transform(() new UpgradeStage))
val wsIn = b.add(Flow[ByteString]) val wsIn = b.add(Flow[ByteString])

View file

@ -44,8 +44,8 @@ class HighLevelOutgoingConnectionSpec extends AkkaSpec {
val connFlow = Http().outgoingConnection(serverHostName, serverPort) val connFlow = Http().outgoingConnection(serverHostName, serverPort)
val C = 4 val C = 4
val doubleConnection = Flow.fromGraph(FlowGraph.create() { implicit b val doubleConnection = Flow.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val bcast = b.add(Broadcast[HttpRequest](C)) val bcast = b.add(Broadcast[HttpRequest](C))
val merge = b.add(Merge[HttpResponse](C)) val merge = b.add(Merge[HttpResponse](C))

View file

@ -526,9 +526,9 @@ class LowLevelOutgoingConnectionSpec extends AkkaSpec("akka.loggers = []\n akka.
val netOut = TestSubscriber.manualProbe[ByteString] val netOut = TestSubscriber.manualProbe[ByteString]
val netIn = TestPublisher.manualProbe[ByteString]() val netIn = TestPublisher.manualProbe[ByteString]()
RunnableGraph.fromGraph(FlowGraph.create(OutgoingConnectionBlueprint(Host("example.com"), settings, NoLogging)) { implicit b RunnableGraph.fromGraph(GraphDSL.create(OutgoingConnectionBlueprint(Host("example.com"), settings, NoLogging)) { implicit b
client client
import FlowGraph.Implicits._ import GraphDSL.Implicits._
Source(netIn) ~> Flow[ByteString].map(SessionBytes(null, _)) ~> client.in2 Source(netIn) ~> Flow[ByteString].map(SessionBytes(null, _)) ~> client.in2
client.out1 ~> Flow[SslTlsOutbound].collect { case SendBytes(x) x } ~> Sink(netOut) client.out1 ~> Flow[SslTlsOutbound].collect { case SendBytes(x) x } ~> Sink(netOut)
Source(requests) ~> client.in1 Source(requests) ~> client.in1

View file

@ -34,9 +34,9 @@ abstract class HttpServerTestSetupBase {
val netIn = TestPublisher.probe[ByteString]() val netIn = TestPublisher.probe[ByteString]()
val netOut = ByteStringSinkProbe() val netOut = ByteStringSinkProbe()
RunnableGraph.fromGraph(FlowGraph.create(HttpServerBluePrint(settings, remoteAddress = remoteAddress, log = NoLogging)) { implicit b RunnableGraph.fromGraph(GraphDSL.create(HttpServerBluePrint(settings, remoteAddress = remoteAddress, log = NoLogging)) { implicit b
server server
import FlowGraph.Implicits._ import GraphDSL.Implicits._
Source(netIn) ~> Flow[ByteString].map(SessionBytes(null, _)) ~> server.in2 Source(netIn) ~> Flow[ByteString].map(SessionBytes(null, _)) ~> server.in2
server.out1 ~> Flow[SslTlsOutbound].collect { case SendBytes(x) x } ~> netOut.sink server.out1 ~> Flow[SslTlsOutbound].collect { case SendBytes(x) x } ~> netOut.sink
server.out2 ~> Sink(requests) server.out2 ~> Sink(requests)

View file

@ -822,7 +822,7 @@ class MessageSpec extends FreeSpec with Matchers with WithMaterializerSpec {
val messageHandler: Flow[Message, Message, Unit] = val messageHandler: Flow[Message, Message, Unit] =
Flow.fromGraph { Flow.fromGraph {
FlowGraph.create() { implicit b GraphDSL.create() { implicit b
val in = b.add(Sink(messageIn)).inlet val in = b.add(Sink(messageIn)).inlet
val out = b.add(Source(messageOut)).outlet val out = b.add(Source(messageOut)).outlet

View file

@ -312,9 +312,9 @@ class WebsocketClientSpec extends FreeSpec with Matchers with WithMaterializerSp
val netIn = TestPublisher.probe[ByteString]() val netIn = TestPublisher.probe[ByteString]()
val graph = val graph =
RunnableGraph.fromGraph(FlowGraph.create(clientLayer) { implicit b RunnableGraph.fromGraph(GraphDSL.create(clientLayer) { implicit b
client client
import FlowGraph.Implicits._ import GraphDSL.Implicits._
Source(netIn) ~> Flow[ByteString].map(SessionBytes(null, _)) ~> client.in2 Source(netIn) ~> Flow[ByteString].map(SessionBytes(null, _)) ~> client.in2
client.out1 ~> Flow[SslTlsOutbound].collect { case SendBytes(x) x } ~> netOut.sink client.out1 ~> Flow[SslTlsOutbound].collect { case SendBytes(x) x } ~> netOut.sink
client.out2 ~> clientImplementation ~> client.in1 client.out2 ~> clientImplementation ~> client.in1

View file

@ -9,18 +9,18 @@ import akka.stream.testkit.Utils._
abstract class TwoStreamsSetup extends BaseTwoStreamsSetup { abstract class TwoStreamsSetup extends BaseTwoStreamsSetup {
abstract class Fixture(b: FlowGraph.Builder[_]) { abstract class Fixture(b: GraphDSL.Builder[_]) {
def left: Inlet[Int] def left: Inlet[Int]
def right: Inlet[Int] def right: Inlet[Int]
def out: Outlet[Outputs] def out: Outlet[Outputs]
} }
def fixture(b: FlowGraph.Builder[_]): Fixture def fixture(b: GraphDSL.Builder[_]): Fixture
override def setup(p1: Publisher[Int], p2: Publisher[Int]) = { override def setup(p1: Publisher[Int], p2: Publisher[Int]) = {
val subscriber = TestSubscriber.probe[Outputs]() val subscriber = TestSubscriber.probe[Outputs]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val f = fixture(b) val f = fixture(b)
Source(p1) ~> f.left Source(p1) ~> f.left

View file

@ -19,7 +19,7 @@ import scala.runtime.BoxedUnit;
import akka.japi.Pair; import akka.japi.Pair;
import akka.stream.*; import akka.stream.*;
import akka.stream.testkit.AkkaSpec; import akka.stream.testkit.AkkaSpec;
import akka.stream.javadsl.FlowGraph.Builder; import akka.stream.javadsl.GraphDSL.Builder;
import akka.japi.function.*; import akka.japi.function.*;
import akka.util.ByteString; import akka.util.ByteString;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -35,8 +35,8 @@ public class BidiFlowTest extends StreamTest {
"FlowTest", AkkaSpec.testConf()); "FlowTest", AkkaSpec.testConf());
private final BidiFlow<Integer, Long, ByteString, String, BoxedUnit> bidi = BidiFlow private final BidiFlow<Integer, Long, ByteString, String, BoxedUnit> bidi = BidiFlow
.fromGraph(FlowGraph.create( .fromGraph(GraphDSL.create(
new Function<FlowGraph.Builder<BoxedUnit>, BidiShape<Integer, Long, ByteString, String>>() { new Function<GraphDSL.Builder<BoxedUnit>, BidiShape<Integer, Long, ByteString, String>>() {
@Override @Override
public BidiShape<Integer, Long, ByteString, String> apply(Builder<BoxedUnit> b) public BidiShape<Integer, Long, ByteString, String> apply(Builder<BoxedUnit> b)
throws Exception { throws Exception {
@ -61,8 +61,8 @@ public class BidiFlowTest extends StreamTest {
private final BidiFlow<Long, Integer, String, ByteString, BoxedUnit> inverse = BidiFlow private final BidiFlow<Long, Integer, String, ByteString, BoxedUnit> inverse = BidiFlow
.fromGraph( .fromGraph(
FlowGraph.create( GraphDSL.create(
new Function<FlowGraph.Builder<BoxedUnit>, BidiShape<Long, Integer, String, ByteString>>() { new Function<GraphDSL.Builder<BoxedUnit>, BidiShape<Long, Integer, String, ByteString>>() {
@Override @Override
public BidiShape<Long, Integer, String, ByteString> apply(Builder<BoxedUnit> b) public BidiShape<Long, Integer, String, ByteString> apply(Builder<BoxedUnit> b)
throws Exception { throws Exception {
@ -87,9 +87,9 @@ public class BidiFlowTest extends StreamTest {
private final BidiFlow<Integer, Long, ByteString, String, Future<Integer>> bidiMat = private final BidiFlow<Integer, Long, ByteString, String, Future<Integer>> bidiMat =
BidiFlow.fromGraph( BidiFlow.fromGraph(
FlowGraph.create( GraphDSL.create(
Sink.<Integer>head(), Sink.<Integer>head(),
new Function2<FlowGraph.Builder<Future<Integer>>, SinkShape<Integer>, BidiShape<Integer, Long, ByteString, String>>() { new Function2<GraphDSL.Builder<Future<Integer>>, SinkShape<Integer>, BidiShape<Integer, Long, ByteString, String>>() {
@Override @Override
public BidiShape<Integer, Long, ByteString, String> apply(Builder<Future<Integer>> b, SinkShape<Integer> sink) public BidiShape<Integer, Long, ByteString, String> apply(Builder<Future<Integer>> b, SinkShape<Integer> sink)
throws Exception { throws Exception {
@ -126,7 +126,7 @@ public class BidiFlowTest extends StreamTest {
@Test @Test
public void mustWorkInIsolation() throws Exception { public void mustWorkInIsolation() throws Exception {
final Pair<Future<Long>, Future<String>> p = final Pair<Future<Long>, Future<String>> p =
RunnableGraph.fromGraph(FlowGraph RunnableGraph.fromGraph(GraphDSL
.create(Sink.<Long> head(), Sink.<String> head(), .create(Sink.<Long> head(), Sink.<String> head(),
Keep.<Future<Long>, Future<String>> both(), Keep.<Future<Long>, Future<String>> both(),
new Function3<Builder<Pair<Future<Long>, Future<String>>>, SinkShape<Long>, SinkShape<String>, ClosedShape>() { new Function3<Builder<Pair<Future<Long>, Future<String>>>, SinkShape<Long>, SinkShape<String>, ClosedShape>() {
@ -202,7 +202,7 @@ public class BidiFlowTest extends StreamTest {
@Test @Test
public void mustMaterializeToItsValue() throws Exception { public void mustMaterializeToItsValue() throws Exception {
final Future<Integer> f = RunnableGraph.fromGraph( final Future<Integer> f = RunnableGraph.fromGraph(
FlowGraph.create(bidiMat, GraphDSL.create(bidiMat,
new Function2<Builder<Future<Integer> >, BidiShape<Integer, Long, ByteString, String>, ClosedShape>() { new Function2<Builder<Future<Integer> >, BidiShape<Integer, Long, ByteString, String>, ClosedShape>() {
@Override @Override
public ClosedShape apply(Builder<Future<Integer>> b, public ClosedShape apply(Builder<Future<Integer>> b,
@ -231,7 +231,7 @@ public class BidiFlowTest extends StreamTest {
@Test @Test
public void mustCombineMaterializationValues() throws Exception { public void mustCombineMaterializationValues() throws Exception {
final Flow<String, Integer, Future<Integer>> left = Flow.fromGraph(FlowGraph.create( final Flow<String, Integer, Future<Integer>> left = Flow.fromGraph(GraphDSL.create(
Sink.<Integer>head(), new Function2<Builder<Future<Integer>>, SinkShape<Integer>, FlowShape<String, Integer>>() { Sink.<Integer>head(), new Function2<Builder<Future<Integer>>, SinkShape<Integer>, FlowShape<String, Integer>>() {
@Override @Override
public FlowShape<String, Integer> apply(Builder<Future<Integer>> b, public FlowShape<String, Integer> apply(Builder<Future<Integer>> b,
@ -251,7 +251,7 @@ public class BidiFlowTest extends StreamTest {
return new FlowShape<String, Integer>(flow.inlet(), merge.out()); return new FlowShape<String, Integer>(flow.inlet(), merge.out());
} }
})); }));
final Flow<Long, ByteString, Future<List<Long>>> right = Flow.fromGraph(FlowGraph.create( final Flow<Long, ByteString, Future<List<Long>>> right = Flow.fromGraph(GraphDSL.create(
Sink.<List<Long>>head(), new Function2<Builder<Future<List<Long>>>, SinkShape<List<Long>>, FlowShape<Long, ByteString>>() { Sink.<List<Long>>head(), new Function2<Builder<Future<List<Long>>>, SinkShape<List<Long>>, FlowShape<Long, ByteString>>() {
@Override @Override
public FlowShape<Long, ByteString> apply(Builder<Future<List<Long>>> b, public FlowShape<Long, ByteString> apply(Builder<Future<List<Long>>> b,

View file

@ -7,7 +7,7 @@ import akka.japi.Pair;
import akka.pattern.Patterns; import akka.pattern.Patterns;
import akka.japi.tuple.Tuple4; import akka.japi.tuple.Tuple4;
import akka.stream.*; import akka.stream.*;
import akka.stream.javadsl.FlowGraph.Builder; import akka.stream.javadsl.GraphDSL.Builder;
import akka.stream.stage.*; import akka.stream.stage.*;
import akka.japi.function.*; import akka.japi.function.*;
import akka.stream.testkit.AkkaSpec; import akka.stream.testkit.AkkaSpec;
@ -70,7 +70,7 @@ public class FlowGraphTest extends StreamTest {
final Sink<String, Publisher<String>> publisher = Sink.publisher(false); final Sink<String, Publisher<String>> publisher = Sink.publisher(false);
final Source<String, BoxedUnit> source = Source.fromGraph( final Source<String, BoxedUnit> source = Source.fromGraph(
FlowGraph.create(new Function<FlowGraph.Builder<BoxedUnit>, SourceShape<String>>() { GraphDSL.create(new Function<GraphDSL.Builder<BoxedUnit>, SourceShape<String>>() {
@Override @Override
public SourceShape<String> apply(Builder<BoxedUnit> b) throws Exception { public SourceShape<String> apply(Builder<BoxedUnit> b) throws Exception {
final UniformFanInShape<String, String> merge = b.add(Merge.<String>create(2)); final UniformFanInShape<String, String> merge = b.add(Merge.<String>create(2));
@ -94,7 +94,7 @@ public class FlowGraphTest extends StreamTest {
final Iterable<String> input1 = Arrays.asList("A", "B", "C"); final Iterable<String> input1 = Arrays.asList("A", "B", "C");
final Iterable<Integer> input2 = Arrays.asList(1, 2, 3); final Iterable<Integer> input2 = Arrays.asList(1, 2, 3);
RunnableGraph.fromGraph( FlowGraph.create( RunnableGraph.fromGraph( GraphDSL.create(
new Function<Builder<BoxedUnit>,ClosedShape>() { new Function<Builder<BoxedUnit>,ClosedShape>() {
@Override @Override
public ClosedShape apply(final Builder<BoxedUnit> b) throws Exception { public ClosedShape apply(final Builder<BoxedUnit> b) throws Exception {
@ -129,7 +129,7 @@ public class FlowGraphTest extends StreamTest {
final Iterable<String> expected1 = Arrays.asList("A", "B", "C"); final Iterable<String> expected1 = Arrays.asList("A", "B", "C");
final Iterable<Integer> expected2 = Arrays.asList(1, 2, 3); final Iterable<Integer> expected2 = Arrays.asList(1, 2, 3);
RunnableGraph.fromGraph(FlowGraph.create( RunnableGraph.fromGraph(GraphDSL.create(
new Function<Builder<BoxedUnit>, ClosedShape>() { new Function<Builder<BoxedUnit>, ClosedShape>() {
@Override @Override
public ClosedShape apply(final Builder<BoxedUnit> b) throws Exception { public ClosedShape apply(final Builder<BoxedUnit> b) throws Exception {
@ -161,7 +161,7 @@ public class FlowGraphTest extends StreamTest {
final JavaTestKit probe1 = new JavaTestKit(system); final JavaTestKit probe1 = new JavaTestKit(system);
final JavaTestKit probe2 = new JavaTestKit(system); final JavaTestKit probe2 = new JavaTestKit(system);
RunnableGraph.fromGraph(FlowGraph.create( RunnableGraph.fromGraph(GraphDSL.create(
new Function<Builder<BoxedUnit>, ClosedShape>() { new Function<Builder<BoxedUnit>, ClosedShape>() {
@Override @Override
public ClosedShape apply(final Builder<BoxedUnit> b) throws Exception { public ClosedShape apply(final Builder<BoxedUnit> b) throws Exception {
@ -204,7 +204,7 @@ public class FlowGraphTest extends StreamTest {
final JavaTestKit probe3 = new JavaTestKit(system); final JavaTestKit probe3 = new JavaTestKit(system);
final JavaTestKit probe4 = new JavaTestKit(system); final JavaTestKit probe4 = new JavaTestKit(system);
RunnableGraph.fromGraph(FlowGraph.create( RunnableGraph.fromGraph(GraphDSL.create(
new Function<Builder<BoxedUnit>, ClosedShape>() { new Function<Builder<BoxedUnit>, ClosedShape>() {
@Override @Override
public ClosedShape apply(final Builder<BoxedUnit> b) throws Exception { public ClosedShape apply(final Builder<BoxedUnit> b) throws Exception {
@ -258,7 +258,7 @@ public class FlowGraphTest extends StreamTest {
} }
}); });
final Future<Integer> future = RunnableGraph.fromGraph(FlowGraph.create(Sink.<Integer>head(), final Future<Integer> future = RunnableGraph.fromGraph(GraphDSL.create(Sink.<Integer>head(),
new Function2<Builder<Future<Integer>>, SinkShape<Integer>, ClosedShape>() { new Function2<Builder<Future<Integer>>, SinkShape<Integer>, ClosedShape>() {
@Override @Override
public ClosedShape apply(Builder<Future<Integer>> b, SinkShape<Integer> out) throws Exception { public ClosedShape apply(Builder<Future<Integer>> b, SinkShape<Integer> out) throws Exception {
@ -289,7 +289,7 @@ public class FlowGraphTest extends StreamTest {
}); });
final Future<Integer> future = RunnableGraph.fromGraph( final Future<Integer> future = RunnableGraph.fromGraph(
FlowGraph.create(Sink.<Integer>head(), GraphDSL.create(Sink.<Integer>head(),
new Function2<Builder<Future<Integer>>, SinkShape<Integer>, ClosedShape>() { new Function2<Builder<Future<Integer>>, SinkShape<Integer>, ClosedShape>() {
@Override @Override
public ClosedShape apply(Builder<Future<Integer>> b, SinkShape<Integer> out) throws Exception { public ClosedShape apply(Builder<Future<Integer>> b, SinkShape<Integer> out) throws Exception {
@ -314,7 +314,7 @@ public class FlowGraphTest extends StreamTest {
final TestProbe probe = TestProbe.apply(system); final TestProbe probe = TestProbe.apply(system);
final Future<Integer> future = RunnableGraph.fromGraph( final Future<Integer> future = RunnableGraph.fromGraph(
FlowGraph.create(Sink.<Integer> head(), new Function2<Builder<Future<Integer>>, SinkShape<Integer>, ClosedShape>() { GraphDSL.create(Sink.<Integer> head(), new Function2<Builder<Future<Integer>>, SinkShape<Integer>, ClosedShape>() {
@Override @Override
public ClosedShape apply(Builder<Future<Integer>> b, SinkShape<Integer> out) throws Exception { public ClosedShape apply(Builder<Future<Integer>> b, SinkShape<Integer> out) throws Exception {
b.from(b.add(Source.single(1))).to(out); b.from(b.add(Source.single(1))).to(out);

View file

@ -11,7 +11,7 @@ import akka.japi.Pair;
import akka.japi.function.*; import akka.japi.function.*;
import akka.stream.*; import akka.stream.*;
import akka.stream.impl.ConstantFun; import akka.stream.impl.ConstantFun;
import akka.stream.javadsl.FlowGraph.Builder; import akka.stream.javadsl.GraphDSL.Builder;
import akka.stream.stage.*; import akka.stream.stage.*;
import akka.stream.testkit.AkkaSpec; import akka.stream.testkit.AkkaSpec;
import akka.stream.testkit.TestPublisher; import akka.stream.testkit.TestPublisher;
@ -390,7 +390,7 @@ public class FlowTest extends StreamTest {
final Sink<String, Publisher<String>> publisher = Sink.publisher(false); final Sink<String, Publisher<String>> publisher = Sink.publisher(false);
final Source<String, BoxedUnit> source = Source.fromGraph( final Source<String, BoxedUnit> source = Source.fromGraph(
FlowGraph.create(new Function<FlowGraph.Builder<BoxedUnit>, SourceShape<String>>() { GraphDSL.create(new Function<GraphDSL.Builder<BoxedUnit>, SourceShape<String>>() {
@Override @Override
public SourceShape<String> apply(Builder<BoxedUnit> b) throws Exception { public SourceShape<String> apply(Builder<BoxedUnit> b) throws Exception {
final UniformFanInShape<String, String> merge = b.add(Merge.<String>create(2)); final UniformFanInShape<String, String> merge = b.add(Merge.<String>create(2));
@ -414,7 +414,7 @@ public class FlowTest extends StreamTest {
final Iterable<String> input1 = Arrays.asList("A", "B", "C"); final Iterable<String> input1 = Arrays.asList("A", "B", "C");
final Iterable<Integer> input2 = Arrays.asList(1, 2, 3); final Iterable<Integer> input2 = Arrays.asList(1, 2, 3);
RunnableGraph.fromGraph(FlowGraph.create(new Function<Builder<BoxedUnit>, ClosedShape>(){ RunnableGraph.fromGraph(GraphDSL.create(new Function<Builder<BoxedUnit>, ClosedShape>(){
public ClosedShape apply(Builder<BoxedUnit> b) { public ClosedShape apply(Builder<BoxedUnit> b) {
final Outlet<String> in1 = b.add(Source.from(input1)).outlet(); final Outlet<String> in1 = b.add(Source.from(input1)).outlet();
final Outlet<Integer> in2 = b.add(Source.from(input2)).outlet(); final Outlet<Integer> in2 = b.add(Source.from(input2)).outlet();
@ -646,7 +646,7 @@ public class FlowTest extends StreamTest {
@Test @Test
public void mustBeAbleToBroadcastEagerCancel() throws Exception { public void mustBeAbleToBroadcastEagerCancel() throws Exception {
final Sink<String, BoxedUnit> sink = Sink.fromGraph( final Sink<String, BoxedUnit> sink = Sink.fromGraph(
FlowGraph.create(new Function<FlowGraph.Builder<BoxedUnit>, SinkShape<String>>() { GraphDSL.create(new Function<GraphDSL.Builder<BoxedUnit>, SinkShape<String>>() {
@Override @Override
public SinkShape<String> apply(Builder<BoxedUnit> b) throws Exception { public SinkShape<String> apply(Builder<BoxedUnit> b) throws Exception {
final UniformFanOutShape<String, String> broadcast = b.add(Broadcast.<String>create(2, true)); final UniformFanOutShape<String, String> broadcast = b.add(Broadcast.<String>create(2, true));

View file

@ -70,7 +70,7 @@ class DslFactoriesConsistencySpec extends WordSpec with Matchers {
TestCase("Flow", scaladsl.Flow.getClass, javadsl.Flow.getClass), TestCase("Flow", scaladsl.Flow.getClass, javadsl.Flow.getClass),
TestCase("Sink", scaladsl.Sink.getClass, javadsl.Sink.getClass), TestCase("Sink", scaladsl.Sink.getClass, javadsl.Sink.getClass),
TestCase("BidiFlow", scaladsl.BidiFlow.getClass, javadsl.BidiFlow.getClass), TestCase("BidiFlow", scaladsl.BidiFlow.getClass, javadsl.BidiFlow.getClass),
TestCase("FlowGraph", scaladsl.FlowGraph.getClass, javadsl.FlowGraph.getClass, classOf[javadsl.GraphCreate]), TestCase("GraphDSL", scaladsl.GraphDSL.getClass, javadsl.GraphDSL.getClass, classOf[javadsl.GraphCreate]),
TestCase("ZipWith", Some(scaladsl.ZipWith.getClass), None, Some(javadsl.ZipWith.getClass)), TestCase("ZipWith", Some(scaladsl.ZipWith.getClass), None, Some(javadsl.ZipWith.getClass)),
TestCase("Merge", scaladsl.Merge.getClass, javadsl.Merge.getClass), TestCase("Merge", scaladsl.Merge.getClass, javadsl.Merge.getClass),
TestCase("MergePreferred", scaladsl.MergePreferred.getClass, javadsl.MergePreferred.getClass), TestCase("MergePreferred", scaladsl.MergePreferred.getClass, javadsl.MergePreferred.getClass),
@ -113,8 +113,8 @@ class DslFactoriesConsistencySpec extends WordSpec with Matchers {
Ignore(_ == akka.stream.scaladsl.Flow.getClass, _ == "apply", _ == 24, _ true), Ignore(_ == akka.stream.scaladsl.Flow.getClass, _ == "apply", _ == 24, _ true),
Ignore(_ == akka.stream.scaladsl.Sink.getClass, _ == "apply", _ == 24, _ true), Ignore(_ == akka.stream.scaladsl.Sink.getClass, _ == "apply", _ == 24, _ true),
Ignore(_ == akka.stream.scaladsl.BidiFlow.getClass, _ == "apply", _ == 24, _ true), Ignore(_ == akka.stream.scaladsl.BidiFlow.getClass, _ == "apply", _ == 24, _ true),
Ignore(_ == akka.stream.scaladsl.FlowGraph.getClass, _ == "runnable", _ == 24, _ true), Ignore(_ == akka.stream.scaladsl.GraphDSL.getClass, _ == "runnable", _ == 24, _ true),
Ignore(_ == akka.stream.scaladsl.FlowGraph.getClass, _ == "create", _ == 24, _ true), Ignore(_ == akka.stream.scaladsl.GraphDSL.getClass, _ == "create", _ == 24, _ true),
// all generated methods like scaladsl.Sink$.akka$stream$scaladsl$Sink$$newOnCompleteStage$1 // all generated methods like scaladsl.Sink$.akka$stream$scaladsl$Sink$$newOnCompleteStage$1
Ignore(_ true, _.contains("$"), _ true, _ true)) Ignore(_ true, _.contains("$"), _ true, _ true))

View file

@ -339,7 +339,7 @@ class ActorPublisherSpec extends AkkaSpec(ActorPublisherSpec.config) with Implic
} }
} }
"work in a FlowGraph" in { "work in a GraphDSL" in {
implicit val materializer = ActorMaterializer() implicit val materializer = ActorMaterializer()
val probe1 = TestProbe() val probe1 = TestProbe()
val probe2 = TestProbe() val probe2 = TestProbe()
@ -350,9 +350,9 @@ class ActorPublisherSpec extends AkkaSpec(ActorPublisherSpec.config) with Implic
val sink1 = Sink(ActorSubscriber[String](system.actorOf(receiverProps(probe1.ref)))) val sink1 = Sink(ActorSubscriber[String](system.actorOf(receiverProps(probe1.ref))))
val sink2: Sink[String, ActorRef] = Sink.actorSubscriber(receiverProps(probe2.ref)) val sink2: Sink[String, ActorRef] = Sink.actorSubscriber(receiverProps(probe2.ref))
val senderRef2 = RunnableGraph.fromGraph(FlowGraph.create(Source.actorPublisher[Int](senderProps)) { implicit b val senderRef2 = RunnableGraph.fromGraph(GraphDSL.create(Source.actorPublisher[Int](senderProps)) { implicit b
source2 source2
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val merge = b.add(Merge[Int](2)) val merge = b.add(Merge[Int](2))
val bcast = b.add(Broadcast[String](2)) val bcast = b.add(Broadcast[String](2))

View file

@ -174,8 +174,8 @@ class TimeoutsSpec extends AkkaSpec {
val downWrite = TestPublisher.probe[Int]() val downWrite = TestPublisher.probe[Int]()
val downRead = TestSubscriber.probe[String]() val downRead = TestSubscriber.probe[String]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val timeoutStage = b.add(BidiFlow.bidirectionalIdleTimeout[String, Int](2.seconds)) val timeoutStage = b.add(BidiFlow.bidirectionalIdleTimeout[String, Int](2.seconds))
Source(upWrite) ~> timeoutStage.in1; Source(upWrite) ~> timeoutStage.in1;
timeoutStage.out1 ~> Sink(downRead) timeoutStage.out1 ~> Sink(downRead)
@ -222,8 +222,8 @@ class TimeoutsSpec extends AkkaSpec {
val downWrite = TestPublisher.probe[Int]() val downWrite = TestPublisher.probe[Int]()
val downRead = TestSubscriber.probe[String]() val downRead = TestSubscriber.probe[String]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val timeoutStage = b.add(BidiFlow.bidirectionalIdleTimeout[String, Int](2.seconds)) val timeoutStage = b.add(BidiFlow.bidirectionalIdleTimeout[String, Int](2.seconds))
Source(upWrite) ~> timeoutStage.in1; Source(upWrite) ~> timeoutStage.in1;
timeoutStage.out1 ~> Sink(downRead) timeoutStage.out1 ~> Sink(downRead)

View file

@ -214,9 +214,9 @@ class ActorGraphInterpreterSpec extends AkkaSpec {
val takeAll = Flow[Int].grouped(200).toMat(Sink.head)(Keep.right) val takeAll = Flow[Int].grouped(200).toMat(Sink.head)(Keep.right)
val (f1, f2) = RunnableGraph.fromGraph(FlowGraph.create(takeAll, takeAll)(Keep.both) { implicit b val (f1, f2) = RunnableGraph.fromGraph(GraphDSL.create(takeAll, takeAll)(Keep.both) { implicit b
(out1, out2) (out1, out2)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val bidi = b.add(rotatedBidi) val bidi = b.add(rotatedBidi)
Source(1 to 10) ~> bidi.in1 Source(1 to 10) ~> bidi.in1

View file

@ -85,7 +85,7 @@ class TlsSpec extends AkkaSpec("akka.loglevel=INFO\nakka.actor.debug.receive=off
import system.dispatcher import system.dispatcher
implicit val materializer = ActorMaterializer() implicit val materializer = ActorMaterializer()
import FlowGraph.Implicits._ import GraphDSL.Implicits._
"SslTls" must { "SslTls" must {
@ -399,7 +399,7 @@ class TlsSpec extends AkkaSpec("akka.loglevel=INFO\nakka.actor.debug.receive=off
"reliably cancel subscriptions when TransportIn fails early" in assertAllStagesStopped { "reliably cancel subscriptions when TransportIn fails early" in assertAllStagesStopped {
val ex = new Exception("hello") val ex = new Exception("hello")
val (sub, out1, out2) = val (sub, out1, out2) =
RunnableGraph.fromGraph(FlowGraph.create(Source.subscriber[SslTlsOutbound], Sink.head[ByteString], Sink.head[SslTlsInbound])((_, _, _)) { implicit b RunnableGraph.fromGraph(GraphDSL.create(Source.subscriber[SslTlsOutbound], Sink.head[ByteString], Sink.head[SslTlsInbound])((_, _, _)) { implicit b
(s, o1, o2) (s, o1, o2)
val tls = b.add(clientTls(EagerClose)) val tls = b.add(clientTls(EagerClose))
s ~> tls.in1; tls.out1 ~> o1 s ~> tls.in1; tls.out1 ~> o1
@ -417,7 +417,7 @@ class TlsSpec extends AkkaSpec("akka.loglevel=INFO\nakka.actor.debug.receive=off
"reliably cancel subscriptions when UserIn fails early" in assertAllStagesStopped { "reliably cancel subscriptions when UserIn fails early" in assertAllStagesStopped {
val ex = new Exception("hello") val ex = new Exception("hello")
val (sub, out1, out2) = val (sub, out1, out2) =
RunnableGraph.fromGraph(FlowGraph.create(Source.subscriber[ByteString], Sink.head[ByteString], Sink.head[SslTlsInbound])((_, _, _)) { implicit b RunnableGraph.fromGraph(GraphDSL.create(Source.subscriber[ByteString], Sink.head[ByteString], Sink.head[SslTlsInbound])((_, _, _)) { implicit b
(s, o1, o2) (s, o1, o2)
val tls = b.add(clientTls(EagerClose)) val tls = b.add(clientTls(EagerClose))
Source.failed[SslTlsOutbound](ex) ~> tls.in1; tls.out1 ~> o1 Source.failed[SslTlsOutbound](ex) ~> tls.in1; tls.out1 ~> o1

View file

@ -14,7 +14,7 @@ import scala.collection.immutable
class BidiFlowSpec extends AkkaSpec with ConversionCheckedTripleEquals { class BidiFlowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
import Attributes._ import Attributes._
import FlowGraph.Implicits._ import GraphDSL.Implicits._
implicit val mat = ActorMaterializer() implicit val mat = ActorMaterializer()
@ -26,7 +26,7 @@ class BidiFlowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
Flow[Long].map(x x.toInt + 2).withAttributes(name("top")), Flow[Long].map(x x.toInt + 2).withAttributes(name("top")),
Flow[String].map(ByteString(_)).withAttributes(name("bottom"))) Flow[String].map(ByteString(_)).withAttributes(name("bottom")))
val bidiMat = BidiFlow.fromGraph(FlowGraph.create(Sink.head[Int]) { implicit b val bidiMat = BidiFlow.fromGraph(GraphDSL.create(Sink.head[Int]) { implicit b
s s
Source.single(42) ~> s Source.single(42) ~> s
@ -41,7 +41,7 @@ class BidiFlowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
"A BidiFlow" must { "A BidiFlow" must {
"work top/bottom in isolation" in { "work top/bottom in isolation" in {
val (top, bottom) = RunnableGraph.fromGraph(FlowGraph.create(Sink.head[Long], Sink.head[String])(Keep.both) { implicit b val (top, bottom) = RunnableGraph.fromGraph(GraphDSL.create(Sink.head[Long], Sink.head[String])(Keep.both) { implicit b
(st, sb) (st, sb)
val s = b.add(bidi) val s = b.add(bidi)
@ -80,7 +80,7 @@ class BidiFlowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"materialize to its value" in { "materialize to its value" in {
val f = RunnableGraph.fromGraph(FlowGraph.create(bidiMat) { implicit b val f = RunnableGraph.fromGraph(GraphDSL.create(bidiMat) { implicit b
bidi bidi
Flow[String].map(Integer.valueOf(_).toInt) <~> bidi <~> Flow[Long].map(x ByteString(s"Hello $x")) Flow[String].map(Integer.valueOf(_).toInt) <~> bidi <~> Flow[Long].map(x ByteString(s"Hello $x"))
ClosedShape ClosedShape
@ -89,7 +89,7 @@ class BidiFlowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"combine materialization values" in assertAllStagesStopped { "combine materialization values" in assertAllStagesStopped {
val left = Flow.fromGraph(FlowGraph.create(Sink.head[Int]) { implicit b val left = Flow.fromGraph(GraphDSL.create(Sink.head[Int]) { implicit b
sink sink
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))
val merge = b.add(Merge[Int](2)) val merge = b.add(Merge[Int](2))
@ -99,7 +99,7 @@ class BidiFlowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
flow ~> merge flow ~> merge
FlowShape(flow.inlet, merge.out) FlowShape(flow.inlet, merge.out)
}) })
val right = Flow.fromGraph(FlowGraph.create(Sink.head[immutable.Seq[Long]]) { implicit b val right = Flow.fromGraph(GraphDSL.create(Sink.head[immutable.Seq[Long]]) { implicit b
sink sink
val flow = b.add(Flow[Long].grouped(10)) val flow = b.add(Flow[Long].grouped(10))
flow ~> sink flow ~> sink

View file

@ -40,9 +40,9 @@ class FlowGraphCompileSpec extends AkkaSpec {
val out2 = Sink.head[String] val out2 = Sink.head[String]
"A Graph" should { "A Graph" should {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
"build simple merge" in { "build simple merge" in {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val merge = b.add(Merge[String](2)) val merge = b.add(Merge[String](2))
in1 ~> f1 ~> merge.in(0) in1 ~> f1 ~> merge.in(0)
in2 ~> f2 ~> merge.in(1) in2 ~> f2 ~> merge.in(1)
@ -52,7 +52,7 @@ class FlowGraphCompileSpec extends AkkaSpec {
} }
"build simple broadcast" in { "build simple broadcast" in {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val bcast = b.add(Broadcast[String](2)) val bcast = b.add(Broadcast[String](2))
in1 ~> f1 ~> bcast.in in1 ~> f1 ~> bcast.in
bcast.out(0) ~> f2 ~> out1 bcast.out(0) ~> f2 ~> out1
@ -62,7 +62,7 @@ class FlowGraphCompileSpec extends AkkaSpec {
} }
"build simple balance" in { "build simple balance" in {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val balance = b.add(Balance[String](2)) val balance = b.add(Balance[String](2))
in1 ~> f1 ~> balance.in in1 ~> f1 ~> balance.in
balance.out(0) ~> f2 ~> out1 balance.out(0) ~> f2 ~> out1
@ -72,7 +72,7 @@ class FlowGraphCompileSpec extends AkkaSpec {
} }
"build simple merge - broadcast" in { "build simple merge - broadcast" in {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val merge = b.add(Merge[String](2)) val merge = b.add(Merge[String](2))
val bcast = b.add(Broadcast[String](2)) val bcast = b.add(Broadcast[String](2))
in1 ~> f1 ~> merge.in(0) in1 ~> f1 ~> merge.in(0)
@ -85,8 +85,8 @@ class FlowGraphCompileSpec extends AkkaSpec {
} }
"build simple merge - broadcast with implicits" in { "build simple merge - broadcast with implicits" in {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val merge = b.add(Merge[String](2)) val merge = b.add(Merge[String](2))
val bcast = b.add(Broadcast[String](2)) val bcast = b.add(Broadcast[String](2))
b.add(in1) ~> f1 ~> merge.in(0) b.add(in1) ~> f1 ~> merge.in(0)
@ -110,7 +110,7 @@ class FlowGraphCompileSpec extends AkkaSpec {
"detect cycle in " in { "detect cycle in " in {
pending // FIXME needs cycle detection capability pending // FIXME needs cycle detection capability
intercept[IllegalArgumentException] { intercept[IllegalArgumentException] {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val merge = b.add(Merge[String](2)) val merge = b.add(Merge[String](2))
val bcast1 = b.add(Broadcast[String](2)) val bcast1 = b.add(Broadcast[String](2))
val bcast2 = b.add(Broadcast[String](2)) val bcast2 = b.add(Broadcast[String](2))
@ -128,12 +128,12 @@ class FlowGraphCompileSpec extends AkkaSpec {
} }
"express complex topologies in a readable way" in { "express complex topologies in a readable way" in {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val merge = b.add(Merge[String](2)) val merge = b.add(Merge[String](2))
val bcast1 = b.add(Broadcast[String](2)) val bcast1 = b.add(Broadcast[String](2))
val bcast2 = b.add(Broadcast[String](2)) val bcast2 = b.add(Broadcast[String](2))
val feedbackLoopBuffer = Flow[String].buffer(10, OverflowStrategy.dropBuffer) val feedbackLoopBuffer = Flow[String].buffer(10, OverflowStrategy.dropBuffer)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
b.add(in1) ~> f1 ~> merge ~> f2 ~> bcast1 ~> f3 ~> b.add(out1) b.add(in1) ~> f1 ~> merge ~> f2 ~> bcast1 ~> f3 ~> b.add(out1)
bcast1 ~> feedbackLoopBuffer ~> bcast2 ~> f5 ~> merge bcast1 ~> feedbackLoopBuffer ~> bcast2 ~> f5 ~> merge
bcast2 ~> f6 ~> b.add(out2) bcast2 ~> f6 ~> b.add(out2)
@ -142,10 +142,10 @@ class FlowGraphCompileSpec extends AkkaSpec {
} }
"build broadcast - merge" in { "build broadcast - merge" in {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val bcast = b.add(Broadcast[String](2)) val bcast = b.add(Broadcast[String](2))
val merge = b.add(Merge[String](2)) val merge = b.add(Merge[String](2))
import FlowGraph.Implicits._ import GraphDSL.Implicits._
in1 ~> f1 ~> bcast ~> f2 ~> merge ~> f3 ~> out1 in1 ~> f1 ~> bcast ~> f2 ~> merge ~> f3 ~> out1
bcast ~> f4 ~> merge bcast ~> f4 ~> merge
ClosedShape ClosedShape
@ -154,7 +154,7 @@ class FlowGraphCompileSpec extends AkkaSpec {
"build wikipedia Topological_sorting" in { "build wikipedia Topological_sorting" in {
// see https://en.wikipedia.org/wiki/Topological_sorting#mediaviewer/File:Directed_acyclic_graph.png // see https://en.wikipedia.org/wiki/Topological_sorting#mediaviewer/File:Directed_acyclic_graph.png
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val b3 = b.add(Broadcast[String](2)) val b3 = b.add(Broadcast[String](2))
val b7 = b.add(Broadcast[String](2)) val b7 = b.add(Broadcast[String](2))
val b11 = b.add(Broadcast[String](3)) val b11 = b.add(Broadcast[String](3))
@ -169,7 +169,7 @@ class FlowGraphCompileSpec extends AkkaSpec {
val out9 = Sink.publisher[String](false) val out9 = Sink.publisher[String](false)
val out10 = Sink.publisher[String](false) val out10 = Sink.publisher[String](false)
def f(s: String) = Flow[String].transform(op[String, String]).named(s) def f(s: String) = Flow[String].transform(op[String, String]).named(s)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
in7 ~> f("a") ~> b7 ~> f("b") ~> m11 ~> f("c") ~> b11 ~> f("d") ~> out2 in7 ~> f("a") ~> b7 ~> f("b") ~> m11 ~> f("c") ~> b11 ~> f("d") ~> out2
b11 ~> f("e") ~> m9 ~> f("f") ~> out9 b11 ~> f("e") ~> m9 ~> f("f") ~> out9
@ -183,10 +183,10 @@ class FlowGraphCompileSpec extends AkkaSpec {
} }
"make it optional to specify flows" in { "make it optional to specify flows" in {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val merge = b.add(Merge[String](2)) val merge = b.add(Merge[String](2))
val bcast = b.add(Broadcast[String](2)) val bcast = b.add(Broadcast[String](2))
import FlowGraph.Implicits._ import GraphDSL.Implicits._
in1 ~> merge ~> bcast ~> out1 in1 ~> merge ~> bcast ~> out1
in2 ~> merge in2 ~> merge
bcast ~> out2 bcast ~> out2
@ -195,11 +195,11 @@ class FlowGraphCompileSpec extends AkkaSpec {
} }
"build unzip - zip" in { "build unzip - zip" in {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val zip = b.add(Zip[Int, String]()) val zip = b.add(Zip[Int, String]())
val unzip = b.add(Unzip[Int, String]()) val unzip = b.add(Unzip[Int, String]())
val out = Sink.publisher[(Int, String)](false) val out = Sink.publisher[(Int, String)](false)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
Source(List(1 -> "a", 2 -> "b", 3 -> "c")) ~> unzip.in Source(List(1 -> "a", 2 -> "b", 3 -> "c")) ~> unzip.in
unzip.out0 ~> Flow[Int].map(_ * 2) ~> zip.in0 unzip.out0 ~> Flow[Int].map(_ * 2) ~> zip.in0
unzip.out1 ~> zip.in1 unzip.out1 ~> zip.in1
@ -210,7 +210,7 @@ class FlowGraphCompileSpec extends AkkaSpec {
"distinguish between input and output ports" in { "distinguish between input and output ports" in {
intercept[IllegalArgumentException] { intercept[IllegalArgumentException] {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val zip = b.add(Zip[Int, String]()) val zip = b.add(Zip[Int, String]())
val unzip = b.add(Unzip[Int, String]()) val unzip = b.add(Unzip[Int, String]())
val wrongOut = Sink.publisher[(Int, Int)](false) val wrongOut = Sink.publisher[(Int, Int)](false)
@ -227,8 +227,8 @@ class FlowGraphCompileSpec extends AkkaSpec {
} }
"build with variance" in { "build with variance" in {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val merge = b.add(Merge[Fruit](2)) val merge = b.add(Merge[Fruit](2))
Source[Fruit](apples) ~> Flow[Fruit] ~> merge.in(0) Source[Fruit](apples) ~> Flow[Fruit] ~> merge.in(0)
Source[Apple](apples) ~> Flow[Apple] ~> merge.in(1) Source[Apple](apples) ~> Flow[Apple] ~> merge.in(1)
@ -238,8 +238,8 @@ class FlowGraphCompileSpec extends AkkaSpec {
} }
"build with variance when indices are not specified" in { "build with variance when indices are not specified" in {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val fruitMerge = b.add(Merge[Fruit](2)) val fruitMerge = b.add(Merge[Fruit](2))
Source[Fruit](apples) ~> fruitMerge Source[Fruit](apples) ~> fruitMerge
Source[Apple](apples) ~> fruitMerge Source[Apple](apples) ~> fruitMerge
@ -271,7 +271,7 @@ class FlowGraphCompileSpec extends AkkaSpec {
} }
"build with implicits and variance" in { "build with implicits and variance" in {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
def appleSource = b.add(Source(TestPublisher.manualProbe[Apple]())) def appleSource = b.add(Source(TestPublisher.manualProbe[Apple]()))
def fruitSource = b.add(Source(TestPublisher.manualProbe[Fruit]())) def fruitSource = b.add(Source(TestPublisher.manualProbe[Fruit]()))
val outA = b add Sink(TestSubscriber.manualProbe[Fruit]()) val outA = b add Sink(TestSubscriber.manualProbe[Fruit]())
@ -279,7 +279,7 @@ class FlowGraphCompileSpec extends AkkaSpec {
val merge = b add Merge[Fruit](11) val merge = b add Merge[Fruit](11)
val unzip = b add Unzip[Int, String]() val unzip = b add Unzip[Int, String]()
val whatever = b add Sink.publisher[Any](false) val whatever = b add Sink.publisher[Any](false)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
b.add(Source[Fruit](apples)) ~> merge.in(0) b.add(Source[Fruit](apples)) ~> merge.in(0)
appleSource ~> merge.in(1) appleSource ~> merge.in(1)
appleSource ~> merge.in(2) appleSource ~> merge.in(2)
@ -308,32 +308,32 @@ class FlowGraphCompileSpec extends AkkaSpec {
} }
"build with plain flow without junctions" in { "build with plain flow without junctions" in {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
in1 ~> f1 ~> out1 in1 ~> f1 ~> out1
ClosedShape ClosedShape
}).run() }).run()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
in1 ~> f1 ~> f2.to(out1) in1 ~> f1 ~> f2.to(out1)
ClosedShape ClosedShape
}).run() }).run()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
(in1 via f1) ~> f2 ~> out1 (in1 via f1) ~> f2 ~> out1
ClosedShape ClosedShape
}).run() }).run()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
in1 ~> out1 in1 ~> out1
ClosedShape ClosedShape
}).run() }).run()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
in1 ~> (f1 to out1) in1 ~> (f1 to out1)
ClosedShape ClosedShape
}).run() }).run()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
(in1 via f1) ~> out1 (in1 via f1) ~> out1
ClosedShape ClosedShape
}).run() }).run()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
(in1 via f1) ~> (f2 to out1) (in1 via f1) ~> (f2 to out1)
ClosedShape ClosedShape
}).run() }).run()

View file

@ -24,8 +24,8 @@ class FlowJoinSpec extends AkkaSpec(ConfigFactory.parseString("akka.loglevel=INF
val source = Source(0 to end) val source = Source(0 to end)
val probe = TestSubscriber.manualProbe[Seq[Int]]() val probe = TestSubscriber.manualProbe[Seq[Int]]()
val flow1 = Flow.fromGraph(FlowGraph.create() { implicit b val flow1 = Flow.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val merge = b.add(Merge[Int](2)) val merge = b.add(Merge[Int](2))
val broadcast = b.add(Broadcast[Int](2)) val broadcast = b.add(Broadcast[Int](2))
source ~> merge.in(0) source ~> merge.in(0)

View file

@ -33,8 +33,8 @@ class FlowSectionSpec extends AkkaSpec(FlowSectionSpec.config) {
} }
"have a nested flow with a different dispatcher" in { "have a nested flow with a different dispatcher" in {
val flow = Flow.fromGraph(FlowGraph.create() { implicit b val flow = Flow.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val bcast1 = b.add(Broadcast[Int](1)) val bcast1 = b.add(Broadcast[Int](1))
val bcast2 = b.add(Broadcast[Int](1)) val bcast2 = b.add(Broadcast[Int](1))
bcast1 ~> Flow[Int].map(sendThreadNameTo(testActor)) ~> bcast2.in bcast1 ~> Flow[Int].map(sendThreadNameTo(testActor)) ~> bcast2.in
@ -51,16 +51,16 @@ class FlowSectionSpec extends AkkaSpec(FlowSectionSpec.config) {
val probe1 = TestProbe() val probe1 = TestProbe()
val probe2 = TestProbe() val probe2 = TestProbe()
val flow1 = Flow.fromGraph(FlowGraph.create() { implicit b val flow1 = Flow.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val bcast1 = b.add(Broadcast[Int](1)) val bcast1 = b.add(Broadcast[Int](1))
val bcast2 = b.add(Broadcast[Int](1)) val bcast2 = b.add(Broadcast[Int](1))
bcast1 ~> Flow[Int].map(sendThreadNameTo(probe1.ref)) ~> bcast2.in bcast1 ~> Flow[Int].map(sendThreadNameTo(probe1.ref)) ~> bcast2.in
FlowShape(bcast1.in, bcast2.out(0)) FlowShape(bcast1.in, bcast2.out(0))
}).withAttributes(dispatcher("my-dispatcher1")) }).withAttributes(dispatcher("my-dispatcher1"))
val flow2 = Flow.fromGraph(FlowGraph.create() { implicit b val flow2 = Flow.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val bcast1 = b.add(Broadcast[Int](1)) val bcast1 = b.add(Broadcast[Int](1))
val bcast2 = b.add(Broadcast[Int](1)) val bcast2 = b.add(Broadcast[Int](1))
bcast1 ~> flow1.via(Flow[Int].map(sendThreadNameTo(probe2.ref))) ~> bcast2.in bcast1 ~> flow1.via(Flow[Int].map(sendThreadNameTo(probe2.ref))) ~> bcast2.in

View file

@ -12,8 +12,8 @@ import org.reactivestreams.Subscriber
object GraphFlowSpec { object GraphFlowSpec {
val source1 = Source(0 to 3) val source1 = Source(0 to 3)
val partialGraph = FlowGraph.create() { implicit b val partialGraph = GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val source2 = Source(4 to 9) val source2 = Source(4 to 9)
val source3 = Source.empty[Int] val source3 = Source.empty[Int]
val source4 = Source.empty[String] val source4 = Source.empty[String]
@ -62,9 +62,9 @@ class GraphFlowSpec extends AkkaSpec {
"work with a Source and Sink" in { "work with a Source and Sink" in {
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
val flow = Flow.fromGraph(FlowGraph.create(partialGraph) { implicit b val flow = Flow.fromGraph(GraphDSL.create(partialGraph) { implicit b
partial partial
import FlowGraph.Implicits._ import GraphDSL.Implicits._
FlowShape(partial.inlet, partial.outlet.map(_.toInt).outlet) FlowShape(partial.inlet, partial.outlet.map(_.toInt).outlet)
}) })
@ -76,7 +76,7 @@ class GraphFlowSpec extends AkkaSpec {
"be transformable with a Pipe" in { "be transformable with a Pipe" in {
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
val flow = Flow.fromGraph(FlowGraph.create(partialGraph) { implicit b val flow = Flow.fromGraph(GraphDSL.create(partialGraph) { implicit b
partial FlowShape(partial.inlet, partial.outlet) partial FlowShape(partial.inlet, partial.outlet)
}) })
@ -88,12 +88,12 @@ class GraphFlowSpec extends AkkaSpec {
"work with another GraphFlow" in { "work with another GraphFlow" in {
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
val flow1 = Flow.fromGraph(FlowGraph.create(partialGraph) { implicit b val flow1 = Flow.fromGraph(GraphDSL.create(partialGraph) { implicit b
partial partial
FlowShape(partial.inlet, partial.outlet) FlowShape(partial.inlet, partial.outlet)
}) })
val flow2 = Flow.fromGraph(FlowGraph.create(Flow[String].map(_.toInt)) { implicit b val flow2 = Flow.fromGraph(GraphDSL.create(Flow[String].map(_.toInt)) { implicit b
importFlow importFlow
FlowShape(importFlow.inlet, importFlow.outlet) FlowShape(importFlow.inlet, importFlow.outlet)
}) })
@ -106,12 +106,12 @@ class GraphFlowSpec extends AkkaSpec {
"be reusable multiple times" in { "be reusable multiple times" in {
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
val flow = Flow.fromGraph(FlowGraph.create(Flow[Int].map(_ * 2)) { implicit b val flow = Flow.fromGraph(GraphDSL.create(Flow[Int].map(_ * 2)) { implicit b
importFlow FlowShape(importFlow.inlet, importFlow.outlet) importFlow FlowShape(importFlow.inlet, importFlow.outlet)
}) })
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
Source(1 to 5) ~> flow ~> flow ~> Sink(probe) Source(1 to 5) ~> flow ~> flow ~> Sink(probe)
ClosedShape ClosedShape
}).run() }).run()
@ -124,9 +124,9 @@ class GraphFlowSpec extends AkkaSpec {
"work with a Sink" in { "work with a Sink" in {
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
val source = Source.fromGraph(FlowGraph.create(partialGraph) { implicit b val source = Source.fromGraph(GraphDSL.create(partialGraph) { implicit b
partial partial
import FlowGraph.Implicits._ import GraphDSL.Implicits._
source1 ~> partial.inlet source1 ~> partial.inlet
SourceShape(partial.outlet.map(_.toInt).outlet) SourceShape(partial.outlet.map(_.toInt).outlet)
}) })
@ -149,9 +149,9 @@ class GraphFlowSpec extends AkkaSpec {
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
val source = Source.fromGraph(FlowGraph.create(partialGraph) { implicit b val source = Source.fromGraph(GraphDSL.create(partialGraph) { implicit b
partial partial
import FlowGraph.Implicits._ import GraphDSL.Implicits._
source1 ~> partial.inlet source1 ~> partial.inlet
SourceShape(partial.outlet) SourceShape(partial.outlet)
}) })
@ -164,14 +164,14 @@ class GraphFlowSpec extends AkkaSpec {
"work with an GraphFlow" in { "work with an GraphFlow" in {
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
val source = Source.fromGraph(FlowGraph.create(partialGraph) { implicit b val source = Source.fromGraph(GraphDSL.create(partialGraph) { implicit b
partial partial
import FlowGraph.Implicits._ import GraphDSL.Implicits._
source1 ~> partial.inlet source1 ~> partial.inlet
SourceShape(partial.outlet) SourceShape(partial.outlet)
}) })
val flow = Flow.fromGraph(FlowGraph.create(Flow[String].map(_.toInt)) { implicit b val flow = Flow.fromGraph(GraphDSL.create(Flow[String].map(_.toInt)) { implicit b
importFlow importFlow
FlowShape(importFlow.inlet, importFlow.outlet) FlowShape(importFlow.inlet, importFlow.outlet)
}) })
@ -184,15 +184,15 @@ class GraphFlowSpec extends AkkaSpec {
"be reusable multiple times" in { "be reusable multiple times" in {
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
val source = Source.fromGraph(FlowGraph.create(Source(1 to 5)) { implicit b val source = Source.fromGraph(GraphDSL.create(Source(1 to 5)) { implicit b
s s
import FlowGraph.Implicits._ import GraphDSL.Implicits._
SourceShape(s.outlet.map(_ * 2).outlet) SourceShape(s.outlet.map(_ * 2).outlet)
}) })
RunnableGraph.fromGraph(FlowGraph.create(source, source)(Keep.both) { implicit b RunnableGraph.fromGraph(GraphDSL.create(source, source)(Keep.both) { implicit b
(s1, s2) (s1, s2)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val merge = b.add(Merge[Int](2)) val merge = b.add(Merge[Int](2))
s1.outlet ~> merge.in(0) s1.outlet ~> merge.in(0)
merge.out ~> Sink(probe) merge.out ~> Sink(probe)
@ -208,9 +208,9 @@ class GraphFlowSpec extends AkkaSpec {
"work with a Source" in { "work with a Source" in {
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
val sink = Sink.fromGraph(FlowGraph.create(partialGraph) { implicit b val sink = Sink.fromGraph(GraphDSL.create(partialGraph) { implicit b
partial partial
import FlowGraph.Implicits._ import GraphDSL.Implicits._
partial.outlet.map(_.toInt) ~> Sink(probe) partial.outlet.map(_.toInt) ~> Sink(probe)
SinkShape(partial.inlet) SinkShape(partial.inlet)
}) })
@ -224,7 +224,7 @@ class GraphFlowSpec extends AkkaSpec {
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
val pubSink = Sink.publisher[Int](false) val pubSink = Sink.publisher[Int](false)
val sink = Sink.fromGraph(FlowGraph.create(pubSink) { implicit b val sink = Sink.fromGraph(GraphDSL.create(pubSink) { implicit b
p SinkShape(p.inlet) p SinkShape(p.inlet)
}) })
@ -237,9 +237,9 @@ class GraphFlowSpec extends AkkaSpec {
"be transformable with a Pipe" in { "be transformable with a Pipe" in {
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
val sink = Sink.fromGraph(FlowGraph.create(partialGraph, Flow[String].map(_.toInt))(Keep.both) { implicit b val sink = Sink.fromGraph(GraphDSL.create(partialGraph, Flow[String].map(_.toInt))(Keep.both) { implicit b
(partial, flow) (partial, flow)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
flow.outlet ~> partial.inlet flow.outlet ~> partial.inlet
partial.outlet.map(_.toInt) ~> Sink(probe) partial.outlet.map(_.toInt) ~> Sink(probe)
SinkShape(flow.inlet) SinkShape(flow.inlet)
@ -255,14 +255,14 @@ class GraphFlowSpec extends AkkaSpec {
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
val flow = Flow.fromGraph(FlowGraph.create(partialGraph) { implicit b val flow = Flow.fromGraph(GraphDSL.create(partialGraph) { implicit b
partial partial
FlowShape(partial.inlet, partial.outlet) FlowShape(partial.inlet, partial.outlet)
}) })
val sink = Sink.fromGraph(FlowGraph.create(Flow[String].map(_.toInt)) { implicit b val sink = Sink.fromGraph(GraphDSL.create(Flow[String].map(_.toInt)) { implicit b
flow flow
import FlowGraph.Implicits._ import GraphDSL.Implicits._
flow.outlet ~> Sink(probe) flow.outlet ~> Sink(probe)
SinkShape(flow.inlet) SinkShape(flow.inlet)
}) })
@ -279,29 +279,29 @@ class GraphFlowSpec extends AkkaSpec {
val inSource = Source.subscriber[Int] val inSource = Source.subscriber[Int]
val outSink = Sink.publisher[Int](false) val outSink = Sink.publisher[Int](false)
val flow = Flow.fromGraph(FlowGraph.create(partialGraph) { implicit b val flow = Flow.fromGraph(GraphDSL.create(partialGraph) { implicit b
partial partial
import FlowGraph.Implicits._ import GraphDSL.Implicits._
FlowShape(partial.inlet, partial.outlet.map(_.toInt).outlet) FlowShape(partial.inlet, partial.outlet.map(_.toInt).outlet)
}) })
val source = Source.fromGraph(FlowGraph.create(Flow[Int].map(_.toString), inSource)(Keep.right) { implicit b val source = Source.fromGraph(GraphDSL.create(Flow[Int].map(_.toString), inSource)(Keep.right) { implicit b
(flow, src) (flow, src)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
src.outlet ~> flow.inlet src.outlet ~> flow.inlet
SourceShape(flow.outlet) SourceShape(flow.outlet)
}) })
val sink = Sink.fromGraph(FlowGraph.create(Flow[String].map(_.toInt), outSink)(Keep.right) { implicit b val sink = Sink.fromGraph(GraphDSL.create(Flow[String].map(_.toInt), outSink)(Keep.right) { implicit b
(flow, snk) (flow, snk)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
flow.outlet ~> snk.inlet flow.outlet ~> snk.inlet
SinkShape(flow.inlet) SinkShape(flow.inlet)
}) })
val (m1, m2, m3) = RunnableGraph.fromGraph(FlowGraph.create(source, flow, sink)(Tuple3.apply) { implicit b val (m1, m2, m3) = RunnableGraph.fromGraph(GraphDSL.create(source, flow, sink)(Tuple3.apply) { implicit b
(src, f, snk) (src, f, snk)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
src.outlet.map(_.toInt) ~> f.inlet src.outlet.map(_.toInt) ~> f.inlet
f.outlet.map(_.toString) ~> snk.inlet f.outlet.map(_.toString) ~> snk.inlet
ClosedShape ClosedShape
@ -320,19 +320,19 @@ class GraphFlowSpec extends AkkaSpec {
val inSource = Source.subscriber[Int] val inSource = Source.subscriber[Int]
val outSink = Sink.publisher[Int](false) val outSink = Sink.publisher[Int](false)
val source = Source.fromGraph(FlowGraph.create(inSource) { implicit b val source = Source.fromGraph(GraphDSL.create(inSource) { implicit b
src src
SourceShape(src.outlet) SourceShape(src.outlet)
}) })
val sink = Sink.fromGraph(FlowGraph.create(outSink) { implicit b val sink = Sink.fromGraph(GraphDSL.create(outSink) { implicit b
snk snk
SinkShape(snk.inlet) SinkShape(snk.inlet)
}) })
val (m1, m2) = RunnableGraph.fromGraph(FlowGraph.create(source, sink)(Keep.both) { implicit b val (m1, m2) = RunnableGraph.fromGraph(GraphDSL.create(source, sink)(Keep.both) { implicit b
(src, snk) (src, snk)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
src.outlet ~> snk.inlet src.outlet ~> snk.inlet
ClosedShape ClosedShape
}).run() }).run()

View file

@ -17,13 +17,13 @@ class GraphBalanceSpec extends AkkaSpec {
implicit val materializer = ActorMaterializer(settings) implicit val materializer = ActorMaterializer(settings)
"A balance" must { "A balance" must {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
"balance between subscribers which signal demand" in assertAllStagesStopped { "balance between subscribers which signal demand" in assertAllStagesStopped {
val c1 = TestSubscriber.manualProbe[Int]() val c1 = TestSubscriber.manualProbe[Int]()
val c2 = TestSubscriber.manualProbe[Int]() val c2 = TestSubscriber.manualProbe[Int]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val balance = b.add(Balance[Int](2)) val balance = b.add(Balance[Int](2))
Source(List(1, 2, 3)) ~> balance.in Source(List(1, 2, 3)) ~> balance.in
balance.out(0) ~> Sink(c1) balance.out(0) ~> Sink(c1)
@ -47,7 +47,7 @@ class GraphBalanceSpec extends AkkaSpec {
"support waiting for demand from all downstream subscriptions" in { "support waiting for demand from all downstream subscriptions" in {
val s1 = TestSubscriber.manualProbe[Int]() val s1 = TestSubscriber.manualProbe[Int]()
val p2 = RunnableGraph.fromGraph(FlowGraph.create(Sink.publisher[Int](false)) { implicit b val p2 = RunnableGraph.fromGraph(GraphDSL.create(Sink.publisher[Int](false)) { implicit b
p2Sink p2Sink
val balance = b.add(Balance[Int](2, waitForAllDownstreams = true)) val balance = b.add(Balance[Int](2, waitForAllDownstreams = true))
Source(List(1, 2, 3)) ~> balance.in Source(List(1, 2, 3)) ~> balance.in
@ -78,7 +78,7 @@ class GraphBalanceSpec extends AkkaSpec {
"support waiting for demand from all non-cancelled downstream subscriptions" in assertAllStagesStopped { "support waiting for demand from all non-cancelled downstream subscriptions" in assertAllStagesStopped {
val s1 = TestSubscriber.manualProbe[Int]() val s1 = TestSubscriber.manualProbe[Int]()
val (p2, p3) = RunnableGraph.fromGraph(FlowGraph.create(Sink.publisher[Int](false), Sink.publisher[Int](false))(Keep.both) { implicit b val (p2, p3) = RunnableGraph.fromGraph(GraphDSL.create(Sink.publisher[Int](false), Sink.publisher[Int](false))(Keep.both) { implicit b
(p2Sink, p3Sink) (p2Sink, p3Sink)
val balance = b.add(Balance[Int](3, waitForAllDownstreams = true)) val balance = b.add(Balance[Int](3, waitForAllDownstreams = true))
Source(List(1, 2, 3)) ~> balance.in Source(List(1, 2, 3)) ~> balance.in
@ -113,7 +113,7 @@ class GraphBalanceSpec extends AkkaSpec {
"work with 5-way balance" in { "work with 5-way balance" in {
val sink = Sink.head[Seq[Int]] val sink = Sink.head[Seq[Int]]
val (s1, s2, s3, s4, s5) = RunnableGraph.fromGraph(FlowGraph.create(sink, sink, sink, sink, sink)(Tuple5.apply) { val (s1, s2, s3, s4, s5) = RunnableGraph.fromGraph(GraphDSL.create(sink, sink, sink, sink, sink)(Tuple5.apply) {
implicit b implicit b
(f1, f2, f3, f4, f5) (f1, f2, f3, f4, f5)
val balance = b.add(Balance[Int](5, waitForAllDownstreams = true)) val balance = b.add(Balance[Int](5, waitForAllDownstreams = true))
@ -133,7 +133,7 @@ class GraphBalanceSpec extends AkkaSpec {
val numElementsForSink = 10000 val numElementsForSink = 10000
val outputs = Sink.fold[Int, Int](0)(_ + _) val outputs = Sink.fold[Int, Int](0)(_ + _)
val results = RunnableGraph.fromGraph(FlowGraph.create(outputs, outputs, outputs)(List(_, _, _)) { implicit b val results = RunnableGraph.fromGraph(GraphDSL.create(outputs, outputs, outputs)(List(_, _, _)) { implicit b
(o1, o2, o3) (o1, o2, o3)
val balance = b.add(Balance[Int](3, waitForAllDownstreams = true)) val balance = b.add(Balance[Int](3, waitForAllDownstreams = true))
Source.repeat(1).take(numElementsForSink * 3) ~> balance.in Source.repeat(1).take(numElementsForSink * 3) ~> balance.in
@ -153,7 +153,7 @@ class GraphBalanceSpec extends AkkaSpec {
"fairly balance between three outputs" in { "fairly balance between three outputs" in {
val probe = TestSink.probe[Int] val probe = TestSink.probe[Int]
val (p1, p2, p3) = RunnableGraph.fromGraph(FlowGraph.create(probe, probe, probe)(Tuple3.apply) { implicit b val (p1, p2, p3) = RunnableGraph.fromGraph(GraphDSL.create(probe, probe, probe)(Tuple3.apply) { implicit b
(o1, o2, o3) (o1, o2, o3)
val balance = b.add(Balance[Int](3)) val balance = b.add(Balance[Int](3))
Source(1 to 7) ~> balance.in Source(1 to 7) ~> balance.in
@ -180,7 +180,7 @@ class GraphBalanceSpec extends AkkaSpec {
val c1 = TestSubscriber.manualProbe[Int]() val c1 = TestSubscriber.manualProbe[Int]()
val c2 = TestSubscriber.manualProbe[Int]() val c2 = TestSubscriber.manualProbe[Int]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val balance = b.add(Balance[Int](2)) val balance = b.add(Balance[Int](2))
Source(List(1, 2, 3)) ~> balance.in Source(List(1, 2, 3)) ~> balance.in
balance.out(0) ~> Sink(c1) balance.out(0) ~> Sink(c1)
@ -202,7 +202,7 @@ class GraphBalanceSpec extends AkkaSpec {
val c1 = TestSubscriber.manualProbe[Int]() val c1 = TestSubscriber.manualProbe[Int]()
val c2 = TestSubscriber.manualProbe[Int]() val c2 = TestSubscriber.manualProbe[Int]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val balance = b.add(Balance[Int](2)) val balance = b.add(Balance[Int](2))
Source(List(1, 2, 3)) ~> balance.in Source(List(1, 2, 3)) ~> balance.in
balance.out(0) ~> Sink(c1) balance.out(0) ~> Sink(c1)
@ -225,7 +225,7 @@ class GraphBalanceSpec extends AkkaSpec {
val c1 = TestSubscriber.manualProbe[Int]() val c1 = TestSubscriber.manualProbe[Int]()
val c2 = TestSubscriber.manualProbe[Int]() val c2 = TestSubscriber.manualProbe[Int]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val balance = b.add(Balance[Int](2)) val balance = b.add(Balance[Int](2))
Source(p1.getPublisher) ~> balance.in Source(p1.getPublisher) ~> balance.in
balance.out(0) ~> Sink(c1) balance.out(0) ~> Sink(c1)

View file

@ -17,13 +17,13 @@ class GraphBroadcastSpec extends AkkaSpec {
implicit val materializer = ActorMaterializer(settings) implicit val materializer = ActorMaterializer(settings)
"A broadcast" must { "A broadcast" must {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
"broadcast to other subscriber" in assertAllStagesStopped { "broadcast to other subscriber" in assertAllStagesStopped {
val c1 = TestSubscriber.manualProbe[Int]() val c1 = TestSubscriber.manualProbe[Int]()
val c2 = TestSubscriber.manualProbe[Int]() val c2 = TestSubscriber.manualProbe[Int]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))
Source(List(1, 2, 3)) ~> bcast.in Source(List(1, 2, 3)) ~> bcast.in
bcast.out(0) ~> Flow[Int].buffer(16, OverflowStrategy.backpressure) ~> Sink(c1) bcast.out(0) ~> Flow[Int].buffer(16, OverflowStrategy.backpressure) ~> Sink(c1)
@ -53,7 +53,7 @@ class GraphBroadcastSpec extends AkkaSpec {
val headSink = Sink.head[Seq[Int]] val headSink = Sink.head[Seq[Int]]
import system.dispatcher import system.dispatcher
val result = RunnableGraph.fromGraph(FlowGraph.create( val result = RunnableGraph.fromGraph(GraphDSL.create(
headSink, headSink,
headSink, headSink,
headSink, headSink,
@ -84,7 +84,7 @@ class GraphBroadcastSpec extends AkkaSpec {
(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22) (f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22)
Future.sequence(List(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22)) Future.sequence(List(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22))
val result = RunnableGraph.fromGraph(FlowGraph.create( val result = RunnableGraph.fromGraph(GraphDSL.create(
headSink, headSink, headSink, headSink, headSink, headSink, headSink, headSink, headSink, headSink,
headSink, headSink, headSink, headSink, headSink, headSink, headSink, headSink, headSink, headSink,
headSink, headSink, headSink, headSink, headSink, headSink, headSink, headSink, headSink, headSink,
@ -126,7 +126,7 @@ class GraphBroadcastSpec extends AkkaSpec {
val c1 = TestSubscriber.manualProbe[Int]() val c1 = TestSubscriber.manualProbe[Int]()
val c2 = TestSubscriber.manualProbe[Int]() val c2 = TestSubscriber.manualProbe[Int]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))
Source(List(1, 2, 3)) ~> bcast.in Source(List(1, 2, 3)) ~> bcast.in
bcast.out(0) ~> Flow[Int] ~> Sink(c1) bcast.out(0) ~> Flow[Int] ~> Sink(c1)
@ -148,7 +148,7 @@ class GraphBroadcastSpec extends AkkaSpec {
val c1 = TestSubscriber.manualProbe[Int]() val c1 = TestSubscriber.manualProbe[Int]()
val c2 = TestSubscriber.manualProbe[Int]() val c2 = TestSubscriber.manualProbe[Int]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))
Source(List(1, 2, 3)) ~> bcast.in Source(List(1, 2, 3)) ~> bcast.in
bcast.out(0) ~> Flow[Int].named("identity-a") ~> Sink(c1) bcast.out(0) ~> Flow[Int].named("identity-a") ~> Sink(c1)
@ -171,7 +171,7 @@ class GraphBroadcastSpec extends AkkaSpec {
val c1 = TestSubscriber.manualProbe[Int]() val c1 = TestSubscriber.manualProbe[Int]()
val c2 = TestSubscriber.manualProbe[Int]() val c2 = TestSubscriber.manualProbe[Int]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))
Source(p1.getPublisher) ~> bcast.in Source(p1.getPublisher) ~> bcast.in
bcast.out(0) ~> Flow[Int] ~> Sink(c1) bcast.out(0) ~> Flow[Int] ~> Sink(c1)
@ -200,7 +200,7 @@ class GraphBroadcastSpec extends AkkaSpec {
val c1 = TestSubscriber.manualProbe[Int]() val c1 = TestSubscriber.manualProbe[Int]()
val c2 = TestSubscriber.manualProbe[Int]() val c2 = TestSubscriber.manualProbe[Int]()
val sink = Sink.fromGraph(FlowGraph.create() { implicit b val sink = Sink.fromGraph(GraphDSL.create() { implicit b
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))
bcast.out(0) ~> Sink(c1) bcast.out(0) ~> Sink(c1)
bcast.out(1) ~> Sink(c2) bcast.out(1) ~> Sink(c2)

View file

@ -15,7 +15,7 @@ class GraphConcatSpec extends TwoStreamsSetup {
override type Outputs = Int override type Outputs = Int
override def fixture(b: FlowGraph.Builder[_]): Fixture = new Fixture(b) { override def fixture(b: GraphDSL.Builder[_]): Fixture = new Fixture(b) {
val concat = b add Concat[Outputs]() val concat = b add Concat[Outputs]()
override def left: Inlet[Outputs] = concat.in(0) override def left: Inlet[Outputs] = concat.in(0)
@ -25,12 +25,12 @@ class GraphConcatSpec extends TwoStreamsSetup {
} }
"Concat" must { "Concat" must {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
"work in the happy case" in assertAllStagesStopped { "work in the happy case" in assertAllStagesStopped {
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val concat1 = b add Concat[Int]() val concat1 = b add Concat[Int]()
val concat2 = b add Concat[Int]() val concat2 = b add Concat[Int]()
@ -141,7 +141,7 @@ class GraphConcatSpec extends TwoStreamsSetup {
val promise = Promise[Int]() val promise = Promise[Int]()
val subscriber = TestSubscriber.manualProbe[Int]() val subscriber = TestSubscriber.manualProbe[Int]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val concat = b add Concat[Int]() val concat = b add Concat[Int]()
Source(List(1, 2, 3)) ~> concat.in(0) Source(List(1, 2, 3)) ~> concat.in(0)
Source(promise.future) ~> concat.in(1) Source(promise.future) ~> concat.in(1)

View file

@ -17,7 +17,7 @@ class GraphMatValueSpec extends AkkaSpec {
implicit val materializer = ActorMaterializer(settings) implicit val materializer = ActorMaterializer(settings)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
"A Graph with materialized value" must { "A Graph with materialized value" must {
@ -25,7 +25,7 @@ class GraphMatValueSpec extends AkkaSpec {
"expose the materialized value as source" in { "expose the materialized value as source" in {
val sub = TestSubscriber.manualProbe[Int]() val sub = TestSubscriber.manualProbe[Int]()
val f = RunnableGraph.fromGraph(FlowGraph.create(foldSink) { implicit b val f = RunnableGraph.fromGraph(GraphDSL.create(foldSink) { implicit b
fold fold
Source(1 to 10) ~> fold Source(1 to 10) ~> fold
b.materializedValue.mapAsync(4)(identity) ~> Sink(sub) b.materializedValue.mapAsync(4)(identity) ~> Sink(sub)
@ -42,7 +42,7 @@ class GraphMatValueSpec extends AkkaSpec {
"expose the materialized value as source multiple times" in { "expose the materialized value as source multiple times" in {
val sub = TestSubscriber.manualProbe[Int]() val sub = TestSubscriber.manualProbe[Int]()
val f = RunnableGraph.fromGraph(FlowGraph.create(foldSink) { implicit b val f = RunnableGraph.fromGraph(GraphDSL.create(foldSink) { implicit b
fold fold
val zip = b.add(ZipWith[Int, Int, Int](_ + _)) val zip = b.add(ZipWith[Int, Int, Int](_ + _))
Source(1 to 10) ~> fold Source(1 to 10) ~> fold
@ -61,7 +61,7 @@ class GraphMatValueSpec extends AkkaSpec {
} }
// Exposes the materialized value as a stream value // Exposes the materialized value as a stream value
val foldFeedbackSource: Source[Future[Int], Future[Int]] = Source.fromGraph(FlowGraph.create(foldSink) { implicit b val foldFeedbackSource: Source[Future[Int], Future[Int]] = Source.fromGraph(GraphDSL.create(foldSink) { implicit b
fold fold
Source(1 to 10) ~> fold Source(1 to 10) ~> fold
SourceShape(b.materializedValue) SourceShape(b.materializedValue)
@ -79,7 +79,7 @@ class GraphMatValueSpec extends AkkaSpec {
} }
"work properly with nesting and reusing" in { "work properly with nesting and reusing" in {
val compositeSource1 = Source.fromGraph(FlowGraph.create(foldFeedbackSource, foldFeedbackSource)(Keep.both) { implicit b val compositeSource1 = Source.fromGraph(GraphDSL.create(foldFeedbackSource, foldFeedbackSource)(Keep.both) { implicit b
(s1, s2) (s1, s2)
val zip = b.add(ZipWith[Int, Int, Int](_ + _)) val zip = b.add(ZipWith[Int, Int, Int](_ + _))
@ -88,7 +88,7 @@ class GraphMatValueSpec extends AkkaSpec {
SourceShape(zip.out) SourceShape(zip.out)
}) })
val compositeSource2 = Source.fromGraph(FlowGraph.create(compositeSource1, compositeSource1)(Keep.both) { implicit b val compositeSource2 = Source.fromGraph(GraphDSL.create(compositeSource1, compositeSource1)(Keep.both) { implicit b
(s1, s2) (s1, s2)
val zip = b.add(ZipWith[Int, Int, Int](_ + _)) val zip = b.add(ZipWith[Int, Int, Int](_ + _))
s1.outlet ~> zip.in0 s1.outlet ~> zip.in0

View file

@ -10,11 +10,11 @@ import scala.concurrent.Await
import scala.concurrent.duration._ import scala.concurrent.duration._
class GraphMergePreferredSpec extends TwoStreamsSetup { class GraphMergePreferredSpec extends TwoStreamsSetup {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
override type Outputs = Int override type Outputs = Int
override def fixture(b: FlowGraph.Builder[_]): Fixture = new Fixture(b) { override def fixture(b: GraphDSL.Builder[_]): Fixture = new Fixture(b) {
val merge = b.add(MergePreferred[Outputs](1)) val merge = b.add(MergePreferred[Outputs](1))
override def left: Inlet[Outputs] = merge.preferred override def left: Inlet[Outputs] = merge.preferred
@ -32,7 +32,7 @@ class GraphMergePreferredSpec extends TwoStreamsSetup {
val preferred = Source(Stream.fill(numElements)(1)) val preferred = Source(Stream.fill(numElements)(1))
val aux = Source(Stream.fill(numElements)(2)) val aux = Source(Stream.fill(numElements)(2))
val result = RunnableGraph.fromGraph(FlowGraph.create(Sink.head[Seq[Int]]) { implicit b val result = RunnableGraph.fromGraph(GraphDSL.create(Sink.head[Seq[Int]]) { implicit b
sink sink
val merge = b.add(MergePreferred[Int](3)) val merge = b.add(MergePreferred[Int](3))
preferred ~> merge.preferred preferred ~> merge.preferred
@ -48,7 +48,7 @@ class GraphMergePreferredSpec extends TwoStreamsSetup {
} }
"eventually pass through all elements" in { "eventually pass through all elements" in {
val result = RunnableGraph.fromGraph(FlowGraph.create(Sink.head[Seq[Int]]) { implicit b val result = RunnableGraph.fromGraph(GraphDSL.create(Sink.head[Seq[Int]]) { implicit b
sink sink
val merge = b.add(MergePreferred[Int](3)) val merge = b.add(MergePreferred[Int](3))
Source(1 to 100) ~> merge.preferred Source(1 to 100) ~> merge.preferred
@ -67,7 +67,7 @@ class GraphMergePreferredSpec extends TwoStreamsSetup {
val s = Source(0 to 3) val s = Source(0 to 3)
(the[IllegalArgumentException] thrownBy { (the[IllegalArgumentException] thrownBy {
val g = RunnableGraph.fromGraph(FlowGraph.create() { implicit b val g = RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val merge = b.add(MergePreferred[Int](1)) val merge = b.add(MergePreferred[Int](1))
s ~> merge.preferred s ~> merge.preferred

View file

@ -11,11 +11,11 @@ import akka.stream.testkit._
import akka.stream.testkit.Utils._ import akka.stream.testkit.Utils._
class GraphMergeSpec extends TwoStreamsSetup { class GraphMergeSpec extends TwoStreamsSetup {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
override type Outputs = Int override type Outputs = Int
override def fixture(b: FlowGraph.Builder[_]): Fixture = new Fixture(b) { override def fixture(b: GraphDSL.Builder[_]): Fixture = new Fixture(b) {
val merge = b add Merge[Outputs](2) val merge = b add Merge[Outputs](2)
override def left: Inlet[Outputs] = merge.in(0) override def left: Inlet[Outputs] = merge.in(0)
@ -33,7 +33,7 @@ class GraphMergeSpec extends TwoStreamsSetup {
val source3 = Source(List[Int]()) val source3 = Source(List[Int]())
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val m1 = b.add(Merge[Int](2)) val m1 = b.add(Merge[Int](2))
val m2 = b.add(Merge[Int](2)) val m2 = b.add(Merge[Int](2))
@ -68,7 +68,7 @@ class GraphMergeSpec extends TwoStreamsSetup {
val probe = TestSubscriber.manualProbe[Int]() val probe = TestSubscriber.manualProbe[Int]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val merge = b.add(Merge[Int](6)) val merge = b.add(Merge[Int](6))
source1 ~> merge.in(0) source1 ~> merge.in(0)
@ -154,7 +154,7 @@ class GraphMergeSpec extends TwoStreamsSetup {
val src1 = Source.subscriber[Int] val src1 = Source.subscriber[Int]
val src2 = Source.subscriber[Int] val src2 = Source.subscriber[Int]
val (graphSubscriber1, graphSubscriber2) = RunnableGraph.fromGraph(FlowGraph.create(src1, src2)((_, _)) { implicit b val (graphSubscriber1, graphSubscriber2) = RunnableGraph.fromGraph(GraphDSL.create(src1, src2)((_, _)) { implicit b
(s1, s2) (s1, s2)
val merge = b.add(Merge[Int](2)) val merge = b.add(Merge[Int](2))
s1.outlet ~> merge.in(0) s1.outlet ~> merge.in(0)

View file

@ -9,7 +9,7 @@ import akka.util.ByteString
import org.scalactic.ConversionCheckedTripleEquals import org.scalactic.ConversionCheckedTripleEquals
object GraphOpsIntegrationSpec { object GraphOpsIntegrationSpec {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
object Shuffle { object Shuffle {
@ -30,7 +30,7 @@ object GraphOpsIntegrationSpec {
} }
def apply[In, Out](pipeline: Flow[In, Out, _]): Graph[ShufflePorts[In, Out], Unit] = { def apply[In, Out](pipeline: Flow[In, Out, _]): Graph[ShufflePorts[In, Out], Unit] = {
FlowGraph.create() { implicit b GraphDSL.create() { implicit b
val merge = b.add(Merge[In](2)) val merge = b.add(Merge[In](2))
val balance = b.add(Balance[Out](2)) val balance = b.add(Balance[Out](2))
merge.out ~> pipeline ~> balance.in merge.out ~> pipeline ~> balance.in
@ -44,7 +44,7 @@ object GraphOpsIntegrationSpec {
class GraphOpsIntegrationSpec extends AkkaSpec with ConversionCheckedTripleEquals { class GraphOpsIntegrationSpec extends AkkaSpec with ConversionCheckedTripleEquals {
import akka.stream.scaladsl.GraphOpsIntegrationSpec._ import akka.stream.scaladsl.GraphOpsIntegrationSpec._
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val settings = ActorMaterializerSettings(system) val settings = ActorMaterializerSettings(system)
.withInputBuffer(initialSize = 2, maxSize = 16) .withInputBuffer(initialSize = 2, maxSize = 16)
@ -54,7 +54,7 @@ class GraphOpsIntegrationSpec extends AkkaSpec with ConversionCheckedTripleEqual
"FlowGraphs" must { "FlowGraphs" must {
"support broadcast - merge layouts" in { "support broadcast - merge layouts" in {
val resultFuture = RunnableGraph.fromGraph(FlowGraph.create(Sink.head[Seq[Int]]) { implicit b val resultFuture = RunnableGraph.fromGraph(GraphDSL.create(Sink.head[Seq[Int]]) { implicit b
(sink) (sink)
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))
val merge = b.add(Merge[Int](2)) val merge = b.add(Merge[Int](2))
@ -71,7 +71,7 @@ class GraphOpsIntegrationSpec extends AkkaSpec with ConversionCheckedTripleEqual
"support balance - merge (parallelization) layouts" in { "support balance - merge (parallelization) layouts" in {
val elements = 0 to 10 val elements = 0 to 10
val out = RunnableGraph.fromGraph(FlowGraph.create(Sink.head[Seq[Int]]) { implicit b val out = RunnableGraph.fromGraph(GraphDSL.create(Sink.head[Seq[Int]]) { implicit b
(sink) (sink)
val balance = b.add(Balance[Int](5)) val balance = b.add(Balance[Int](5))
val merge = b.add(Merge[Int](5)) val merge = b.add(Merge[Int](5))
@ -92,7 +92,7 @@ class GraphOpsIntegrationSpec extends AkkaSpec with ConversionCheckedTripleEqual
// see https://en.wikipedia.org/wiki/Topological_sorting#mediaviewer/File:Directed_acyclic_graph.png // see https://en.wikipedia.org/wiki/Topological_sorting#mediaviewer/File:Directed_acyclic_graph.png
val seqSink = Sink.head[Seq[Int]] val seqSink = Sink.head[Seq[Int]]
val (resultFuture2, resultFuture9, resultFuture10) = RunnableGraph.fromGraph(FlowGraph.create(seqSink, seqSink, seqSink)(Tuple3.apply) { implicit b val (resultFuture2, resultFuture9, resultFuture10) = RunnableGraph.fromGraph(GraphDSL.create(seqSink, seqSink, seqSink)(Tuple3.apply) { implicit b
(sink2, sink9, sink10) (sink2, sink9, sink10)
val b3 = b.add(Broadcast[Int](2)) val b3 = b.add(Broadcast[Int](2))
val b7 = b.add(Broadcast[Int](2)) val b7 = b.add(Broadcast[Int](2))
@ -139,7 +139,7 @@ class GraphOpsIntegrationSpec extends AkkaSpec with ConversionCheckedTripleEqual
"allow adding of flows to sources and sinks to flows" in { "allow adding of flows to sources and sinks to flows" in {
val resultFuture = RunnableGraph.fromGraph(FlowGraph.create(Sink.head[Seq[Int]]) { implicit b val resultFuture = RunnableGraph.fromGraph(GraphDSL.create(Sink.head[Seq[Int]]) { implicit b
(sink) (sink)
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))
val merge = b.add(Merge[Int](2)) val merge = b.add(Merge[Int](2))
@ -158,7 +158,7 @@ class GraphOpsIntegrationSpec extends AkkaSpec with ConversionCheckedTripleEqual
val p = Source(List(1, 2, 3)).runWith(Sink.publisher(false)) val p = Source(List(1, 2, 3)).runWith(Sink.publisher(false))
val s = TestSubscriber.manualProbe[Int] val s = TestSubscriber.manualProbe[Int]
val flow = Flow[Int].map(_ * 2) val flow = Flow[Int].map(_ * 2)
RunnableGraph.fromGraph(FlowGraph.create() { implicit builder RunnableGraph.fromGraph(GraphDSL.create() { implicit builder
Source(p) ~> flow ~> Sink(s) Source(p) ~> flow ~> Sink(s)
ClosedShape ClosedShape
}).run() }).run()
@ -173,7 +173,7 @@ class GraphOpsIntegrationSpec extends AkkaSpec with ConversionCheckedTripleEqual
"be possible to use as lego bricks" in { "be possible to use as lego bricks" in {
val shuffler = Shuffle(Flow[Int].map(_ + 1)) val shuffler = Shuffle(Flow[Int].map(_ + 1))
val f: Future[Seq[Int]] = RunnableGraph.fromGraph(FlowGraph.create(shuffler, shuffler, shuffler, Sink.head[Seq[Int]])((_, _, _, fut) fut) { implicit b val f: Future[Seq[Int]] = RunnableGraph.fromGraph(GraphDSL.create(shuffler, shuffler, shuffler, Sink.head[Seq[Int]])((_, _, _, fut) fut) { implicit b
(s1, s2, s3, sink) (s1, s2, s3, sink)
val merge = b.add(Merge[Int](2)) val merge = b.add(Merge[Int](2))

View file

@ -7,7 +7,7 @@ import scala.concurrent.{ Await, Future }
import scala.concurrent.duration._ import scala.concurrent.duration._
class GraphPartialSpec extends AkkaSpec { class GraphPartialSpec extends AkkaSpec {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val settings = ActorMaterializerSettings(system) val settings = ActorMaterializerSettings(system)
.withInputBuffer(initialSize = 2, maxSize = 16) .withInputBuffer(initialSize = 2, maxSize = 16)
@ -15,10 +15,10 @@ class GraphPartialSpec extends AkkaSpec {
implicit val materializer = ActorMaterializer(settings) implicit val materializer = ActorMaterializer(settings)
"FlowFlowGraph.partial" must { "FlowFlowGraph.partial" must {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
"be able to build and reuse simple partial graphs" in { "be able to build and reuse simple partial graphs" in {
val doubler = FlowGraph.create() { implicit b val doubler = GraphDSL.create() { implicit b
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))
val zip = b.add(ZipWith((a: Int, b: Int) a + b)) val zip = b.add(ZipWith((a: Int, b: Int) a + b))
@ -27,7 +27,7 @@ class GraphPartialSpec extends AkkaSpec {
FlowShape(bcast.in, zip.out) FlowShape(bcast.in, zip.out)
} }
val (_, _, result) = RunnableGraph.fromGraph(FlowGraph.create(doubler, doubler, Sink.head[Seq[Int]])(Tuple3.apply) { implicit b val (_, _, result) = RunnableGraph.fromGraph(GraphDSL.create(doubler, doubler, Sink.head[Seq[Int]])(Tuple3.apply) { implicit b
(d1, d2, sink) (d1, d2, sink)
Source(List(1, 2, 3)) ~> d1.inlet Source(List(1, 2, 3)) ~> d1.inlet
d1.outlet ~> d2.inlet d1.outlet ~> d2.inlet
@ -39,7 +39,7 @@ class GraphPartialSpec extends AkkaSpec {
} }
"be able to build and reuse simple materializing partial graphs" in { "be able to build and reuse simple materializing partial graphs" in {
val doubler = FlowGraph.create(Sink.head[Seq[Int]]) { implicit b val doubler = GraphDSL.create(Sink.head[Seq[Int]]) { implicit b
sink sink
val bcast = b.add(Broadcast[Int](3)) val bcast = b.add(Broadcast[Int](3))
val zip = b.add(ZipWith((a: Int, b: Int) a + b)) val zip = b.add(ZipWith((a: Int, b: Int) a + b))
@ -50,7 +50,7 @@ class GraphPartialSpec extends AkkaSpec {
FlowShape(bcast.in, zip.out) FlowShape(bcast.in, zip.out)
} }
val (sub1, sub2, result) = RunnableGraph.fromGraph(FlowGraph.create(doubler, doubler, Sink.head[Seq[Int]])(Tuple3.apply) { implicit b val (sub1, sub2, result) = RunnableGraph.fromGraph(GraphDSL.create(doubler, doubler, Sink.head[Seq[Int]])(Tuple3.apply) { implicit b
(d1, d2, sink) (d1, d2, sink)
Source(List(1, 2, 3)) ~> d1.inlet Source(List(1, 2, 3)) ~> d1.inlet
d1.outlet ~> d2.inlet d1.outlet ~> d2.inlet
@ -66,7 +66,7 @@ class GraphPartialSpec extends AkkaSpec {
"be able to build and reuse complex materializing partial graphs" in { "be able to build and reuse complex materializing partial graphs" in {
val summer = Sink.fold[Int, Int](0)(_ + _) val summer = Sink.fold[Int, Int](0)(_ + _)
val doubler = FlowGraph.create(summer, summer)(Tuple2.apply) { implicit b val doubler = GraphDSL.create(summer, summer)(Tuple2.apply) { implicit b
(s1, s2) (s1, s2)
val bcast = b.add(Broadcast[Int](3)) val bcast = b.add(Broadcast[Int](3))
val bcast2 = b.add(Broadcast[Int](2)) val bcast2 = b.add(Broadcast[Int](2))
@ -82,7 +82,7 @@ class GraphPartialSpec extends AkkaSpec {
FlowShape(bcast.in, bcast2.out(1)) FlowShape(bcast.in, bcast2.out(1))
} }
val (sub1, sub2, result) = RunnableGraph.fromGraph(FlowGraph.create(doubler, doubler, Sink.head[Seq[Int]])(Tuple3.apply) { implicit b val (sub1, sub2, result) = RunnableGraph.fromGraph(GraphDSL.create(doubler, doubler, Sink.head[Seq[Int]])(Tuple3.apply) { implicit b
(d1, d2, sink) (d1, d2, sink)
Source(List(1, 2, 3)) ~> d1.inlet Source(List(1, 2, 3)) ~> d1.inlet
d1.outlet ~> d2.inlet d1.outlet ~> d2.inlet
@ -98,14 +98,14 @@ class GraphPartialSpec extends AkkaSpec {
} }
"be able to expose the ports of imported graphs" in { "be able to expose the ports of imported graphs" in {
val p = FlowGraph.create(Flow[Int].map(_ + 1)) { implicit b val p = GraphDSL.create(Flow[Int].map(_ + 1)) { implicit b
flow flow
FlowShape(flow.inlet, flow.outlet) FlowShape(flow.inlet, flow.outlet)
} }
val fut = RunnableGraph.fromGraph(FlowGraph.create(Sink.head[Int], p)(Keep.left) { implicit b val fut = RunnableGraph.fromGraph(GraphDSL.create(Sink.head[Int], p)(Keep.left) { implicit b
(sink, flow) (sink, flow)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
Source.single(0) ~> flow.inlet Source.single(0) ~> flow.inlet
flow.outlet ~> sink.inlet flow.outlet ~> sink.inlet
ClosedShape ClosedShape

View file

@ -17,13 +17,13 @@ class GraphUnzipSpec extends AkkaSpec {
implicit val materializer = ActorMaterializer(settings) implicit val materializer = ActorMaterializer(settings)
"A unzip" must { "A unzip" must {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
"unzip to two subscribers" in assertAllStagesStopped { "unzip to two subscribers" in assertAllStagesStopped {
val c1 = TestSubscriber.manualProbe[Int]() val c1 = TestSubscriber.manualProbe[Int]()
val c2 = TestSubscriber.manualProbe[String]() val c2 = TestSubscriber.manualProbe[String]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val unzip = b.add(Unzip[Int, String]()) val unzip = b.add(Unzip[Int, String]())
Source(List(1 -> "a", 2 -> "b", 3 -> "c")) ~> unzip.in Source(List(1 -> "a", 2 -> "b", 3 -> "c")) ~> unzip.in
unzip.out1 ~> Flow[String].buffer(16, OverflowStrategy.backpressure) ~> Sink(c2) unzip.out1 ~> Flow[String].buffer(16, OverflowStrategy.backpressure) ~> Sink(c2)
@ -53,7 +53,7 @@ class GraphUnzipSpec extends AkkaSpec {
val c1 = TestSubscriber.manualProbe[Int]() val c1 = TestSubscriber.manualProbe[Int]()
val c2 = TestSubscriber.manualProbe[String]() val c2 = TestSubscriber.manualProbe[String]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val unzip = b.add(Unzip[Int, String]()) val unzip = b.add(Unzip[Int, String]())
Source(List(1 -> "a", 2 -> "b", 3 -> "c")) ~> unzip.in Source(List(1 -> "a", 2 -> "b", 3 -> "c")) ~> unzip.in
unzip.out0 ~> Sink(c1) unzip.out0 ~> Sink(c1)
@ -75,7 +75,7 @@ class GraphUnzipSpec extends AkkaSpec {
val c1 = TestSubscriber.manualProbe[Int]() val c1 = TestSubscriber.manualProbe[Int]()
val c2 = TestSubscriber.manualProbe[String]() val c2 = TestSubscriber.manualProbe[String]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val unzip = b.add(Unzip[Int, String]()) val unzip = b.add(Unzip[Int, String]())
Source(List(1 -> "a", 2 -> "b", 3 -> "c")) ~> unzip.in Source(List(1 -> "a", 2 -> "b", 3 -> "c")) ~> unzip.in
unzip.out0 ~> Sink(c1) unzip.out0 ~> Sink(c1)
@ -98,7 +98,7 @@ class GraphUnzipSpec extends AkkaSpec {
val c1 = TestSubscriber.manualProbe[Int]() val c1 = TestSubscriber.manualProbe[Int]()
val c2 = TestSubscriber.manualProbe[String]() val c2 = TestSubscriber.manualProbe[String]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val unzip = b.add(Unzip[Int, String]()) val unzip = b.add(Unzip[Int, String]())
Source(p1.getPublisher) ~> unzip.in Source(p1.getPublisher) ~> unzip.in
unzip.out0 ~> Sink(c1) unzip.out0 ~> Sink(c1)
@ -125,7 +125,7 @@ class GraphUnzipSpec extends AkkaSpec {
"work with zip" in assertAllStagesStopped { "work with zip" in assertAllStagesStopped {
val c1 = TestSubscriber.manualProbe[(Int, String)]() val c1 = TestSubscriber.manualProbe[(Int, String)]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val zip = b.add(Zip[Int, String]()) val zip = b.add(Zip[Int, String]())
val unzip = b.add(Unzip[Int, String]()) val unzip = b.add(Unzip[Int, String]())
Source(List(1 -> "a", 2 -> "b", 3 -> "c")) ~> unzip.in Source(List(1 -> "a", 2 -> "b", 3 -> "c")) ~> unzip.in

View file

@ -14,7 +14,7 @@ import scala.util.control.NoStackTrace
class GraphUnzipWithSpec extends AkkaSpec { class GraphUnzipWithSpec extends AkkaSpec {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val settings = ActorMaterializerSettings(system) val settings = ActorMaterializerSettings(system)
.withInputBuffer(initialSize = 2, maxSize = 16) .withInputBuffer(initialSize = 2, maxSize = 16)
@ -26,7 +26,7 @@ class GraphUnzipWithSpec extends AkkaSpec {
type LeftOutput = Int type LeftOutput = Int
type RightOutput = String type RightOutput = String
abstract class Fixture(b: FlowGraph.Builder[_]) { abstract class Fixture(b: GraphDSL.Builder[_]) {
def in: Inlet[Int] def in: Inlet[Int]
def left: Outlet[LeftOutput] def left: Outlet[LeftOutput]
def right: Outlet[RightOutput] def right: Outlet[RightOutput]
@ -34,7 +34,7 @@ class GraphUnzipWithSpec extends AkkaSpec {
val f: (Int (Int, String)) = b (b + b, b + "+" + b) val f: (Int (Int, String)) = b (b + b, b + "+" + b)
def fixture(b: FlowGraph.Builder[_]): Fixture = new Fixture(b) { def fixture(b: GraphDSL.Builder[_]): Fixture = new Fixture(b) {
val unzip = b.add(UnzipWith[Int, Int, String](f)) val unzip = b.add(UnzipWith[Int, Int, String](f))
override def in: Inlet[Int] = unzip.in override def in: Inlet[Int] = unzip.in
@ -48,7 +48,7 @@ class GraphUnzipWithSpec extends AkkaSpec {
val leftSubscriber = TestSubscriber.probe[LeftOutput]() val leftSubscriber = TestSubscriber.probe[LeftOutput]()
val rightSubscriber = TestSubscriber.probe[RightOutput]() val rightSubscriber = TestSubscriber.probe[RightOutput]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val f = fixture(b) val f = fixture(b)
Source(p) ~> f.in Source(p) ~> f.in
@ -97,7 +97,7 @@ class GraphUnzipWithSpec extends AkkaSpec {
val leftProbe = TestSubscriber.manualProbe[LeftOutput]() val leftProbe = TestSubscriber.manualProbe[LeftOutput]()
val rightProbe = TestSubscriber.manualProbe[RightOutput]() val rightProbe = TestSubscriber.manualProbe[RightOutput]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val unzip = b.add(UnzipWith(f)) val unzip = b.add(UnzipWith(f))
Source(1 to 4) ~> unzip.in Source(1 to 4) ~> unzip.in
@ -147,7 +147,7 @@ class GraphUnzipWithSpec extends AkkaSpec {
val leftProbe = TestSubscriber.manualProbe[LeftOutput]() val leftProbe = TestSubscriber.manualProbe[LeftOutput]()
val rightProbe = TestSubscriber.manualProbe[RightOutput]() val rightProbe = TestSubscriber.manualProbe[RightOutput]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val unzip = b.add(UnzipWith[Int, Int, String]((b: Int) (1 / b, 1 + "/" + b))) val unzip = b.add(UnzipWith[Int, Int, String]((b: Int) (1 / b, 1 + "/" + b)))
Source(-2 to 2) ~> unzip.in Source(-2 to 2) ~> unzip.in
@ -192,7 +192,7 @@ class GraphUnzipWithSpec extends AkkaSpec {
case class Person(name: String, surname: String, int: Int) case class Person(name: String, surname: String, int: Int)
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val unzip = b.add(UnzipWith((a: Person) Person.unapply(a).get)) val unzip = b.add(UnzipWith((a: Person) Person.unapply(a).get))
Source.single(Person("Caplin", "Capybara", 3)) ~> unzip.in Source.single(Person("Caplin", "Capybara", 3)) ~> unzip.in
@ -228,7 +228,7 @@ class GraphUnzipWithSpec extends AkkaSpec {
val probe15 = TestSubscriber.manualProbe[String]() val probe15 = TestSubscriber.manualProbe[String]()
val probe19 = TestSubscriber.manualProbe[String]() val probe19 = TestSubscriber.manualProbe[String]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val split20 = (a: (List[Int])) val split20 = (a: (List[Int]))
(a(0), a(0).toString, (a(0), a(0).toString,

View file

@ -11,11 +11,11 @@ import scala.concurrent.Await
import scala.concurrent.duration._ import scala.concurrent.duration._
class GraphZipSpec extends TwoStreamsSetup { class GraphZipSpec extends TwoStreamsSetup {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
override type Outputs = (Int, Int) override type Outputs = (Int, Int)
override def fixture(b: FlowGraph.Builder[_]): Fixture = new Fixture(b) { override def fixture(b: GraphDSL.Builder[_]): Fixture = new Fixture(b) {
val zip = b.add(Zip[Int, Int]()) val zip = b.add(Zip[Int, Int]())
override def left: Inlet[Int] = zip.in0 override def left: Inlet[Int] = zip.in0
@ -28,7 +28,7 @@ class GraphZipSpec extends TwoStreamsSetup {
"work in the happy case" in assertAllStagesStopped { "work in the happy case" in assertAllStagesStopped {
val probe = TestSubscriber.manualProbe[(Int, String)]() val probe = TestSubscriber.manualProbe[(Int, String)]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val zip = b.add(Zip[Int, String]()) val zip = b.add(Zip[Int, String]())
Source(1 to 4) ~> zip.in0 Source(1 to 4) ~> zip.in0
@ -57,7 +57,7 @@ class GraphZipSpec extends TwoStreamsSetup {
val upstream1 = TestPublisher.probe[Int]() val upstream1 = TestPublisher.probe[Int]()
val upstream2 = TestPublisher.probe[String]() val upstream2 = TestPublisher.probe[String]()
val completed = RunnableGraph.fromGraph(FlowGraph.create(Sink.ignore) { implicit b val completed = RunnableGraph.fromGraph(GraphDSL.create(Sink.ignore) { implicit b
out out
val zip = b.add(Zip[Int, String]()) val zip = b.add(Zip[Int, String]())
@ -83,7 +83,7 @@ class GraphZipSpec extends TwoStreamsSetup {
val upstream2 = TestPublisher.probe[String]() val upstream2 = TestPublisher.probe[String]()
val downstream = TestSubscriber.probe[(Int, String)]() val downstream = TestSubscriber.probe[(Int, String)]()
RunnableGraph.fromGraph(FlowGraph.create(Sink(downstream)) { implicit b RunnableGraph.fromGraph(GraphDSL.create(Sink(downstream)) { implicit b
out out
val zip = b.add(Zip[Int, String]()) val zip = b.add(Zip[Int, String]())
@ -110,7 +110,7 @@ class GraphZipSpec extends TwoStreamsSetup {
val upstream2 = TestPublisher.probe[String]() val upstream2 = TestPublisher.probe[String]()
val downstream = TestSubscriber.probe[(Int, String)]() val downstream = TestSubscriber.probe[(Int, String)]()
RunnableGraph.fromGraph(FlowGraph.create(Sink(downstream)) { implicit b RunnableGraph.fromGraph(GraphDSL.create(Sink(downstream)) { implicit b
out out
val zip = b.add(Zip[Int, String]()) val zip = b.add(Zip[Int, String]())
@ -139,7 +139,7 @@ class GraphZipSpec extends TwoStreamsSetup {
val upstream2 = TestPublisher.probe[String]() val upstream2 = TestPublisher.probe[String]()
val downstream = TestSubscriber.probe[(Int, String)]() val downstream = TestSubscriber.probe[(Int, String)]()
RunnableGraph.fromGraph(FlowGraph.create(Sink(downstream)) { implicit b RunnableGraph.fromGraph(GraphDSL.create(Sink(downstream)) { implicit b
out out
val zip = b.add(Zip[Int, String]()) val zip = b.add(Zip[Int, String]())
@ -169,7 +169,7 @@ class GraphZipSpec extends TwoStreamsSetup {
val upstream2 = TestPublisher.probe[String]() val upstream2 = TestPublisher.probe[String]()
val downstream = TestSubscriber.probe[(Int, String)]() val downstream = TestSubscriber.probe[(Int, String)]()
RunnableGraph.fromGraph(FlowGraph.create(Sink(downstream)) { implicit b RunnableGraph.fromGraph(GraphDSL.create(Sink(downstream)) { implicit b
out out
val zip = b.add(Zip[Int, String]()) val zip = b.add(Zip[Int, String]())

View file

@ -5,11 +5,11 @@ import scala.concurrent.duration._
import akka.stream._ import akka.stream._
class GraphZipWithSpec extends TwoStreamsSetup { class GraphZipWithSpec extends TwoStreamsSetup {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
override type Outputs = Int override type Outputs = Int
override def fixture(b: FlowGraph.Builder[_]): Fixture = new Fixture(b) { override def fixture(b: GraphDSL.Builder[_]): Fixture = new Fixture(b) {
val zip = b.add(ZipWith((_: Int) + (_: Int))) val zip = b.add(ZipWith((_: Int) + (_: Int)))
override def left: Inlet[Int] = zip.in0 override def left: Inlet[Int] = zip.in0
override def right: Inlet[Int] = zip.in1 override def right: Inlet[Int] = zip.in1
@ -21,7 +21,7 @@ class GraphZipWithSpec extends TwoStreamsSetup {
"work in the happy case" in { "work in the happy case" in {
val probe = TestSubscriber.manualProbe[Outputs]() val probe = TestSubscriber.manualProbe[Outputs]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val zip = b.add(ZipWith((_: Int) + (_: Int))) val zip = b.add(ZipWith((_: Int) + (_: Int)))
Source(1 to 4) ~> zip.in0 Source(1 to 4) ~> zip.in0
Source(10 to 40 by 10) ~> zip.in1 Source(10 to 40 by 10) ~> zip.in1
@ -48,7 +48,7 @@ class GraphZipWithSpec extends TwoStreamsSetup {
"work in the sad case" in { "work in the sad case" in {
val probe = TestSubscriber.manualProbe[Outputs]() val probe = TestSubscriber.manualProbe[Outputs]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val zip = b.add(ZipWith[Int, Int, Int]((_: Int) / (_: Int))) val zip = b.add(ZipWith[Int, Int, Int]((_: Int) / (_: Int)))
Source(1 to 4) ~> zip.in0 Source(1 to 4) ~> zip.in0
@ -111,7 +111,7 @@ class GraphZipWithSpec extends TwoStreamsSetup {
case class Person(name: String, surname: String, int: Int) case class Person(name: String, surname: String, int: Int)
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val zip = b.add(ZipWith(Person.apply _)) val zip = b.add(ZipWith(Person.apply _))
Source.single("Caplin") ~> zip.in0 Source.single("Caplin") ~> zip.in0
@ -134,7 +134,7 @@ class GraphZipWithSpec extends TwoStreamsSetup {
"work with up to 22 inputs" in { "work with up to 22 inputs" in {
val probe = TestSubscriber.manualProbe[String]() val probe = TestSubscriber.manualProbe[String]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val sum19 = (v1: Int, v2: String, v3: Int, v4: String, v5: Int, v6: String, v7: Int, v8: String, v9: Int, v10: String, val sum19 = (v1: Int, v2: String, v3: Int, v4: String, v5: Int, v6: String, v7: Int, v8: String, v9: Int, v10: String,
v11: Int, v12: String, v13: Int, v14: String, v15: Int, v16: String, v17: Int, v18: String, v19: Int) v11: Int, v12: String, v13: Int, v14: String, v15: Int, v16: String, v17: Int, v18: String, v19: Int)

View file

@ -19,9 +19,9 @@ class PublisherSinkSpec extends AkkaSpec {
"be unique when created twice" in assertAllStagesStopped { "be unique when created twice" in assertAllStagesStopped {
val (pub1, pub2) = RunnableGraph.fromGraph(FlowGraph.create(Sink.publisher[Int](false), Sink.publisher[Int](false))(Keep.both) { implicit b val (pub1, pub2) = RunnableGraph.fromGraph(GraphDSL.create(Sink.publisher[Int](false), Sink.publisher[Int](false))(Keep.both) { implicit b
(p1, p2) (p1, p2)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val bcast = b.add(Broadcast[Int](2)) val bcast = b.add(Broadcast[Int](2))

View file

@ -7,7 +7,7 @@ import scala.concurrent.duration._
import org.scalactic.ConversionCheckedTripleEquals import org.scalactic.ConversionCheckedTripleEquals
class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals { class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
implicit val mat = ActorMaterializer() implicit val mat = ActorMaterializer()
val source = Source(List(1, 2, 3)) val source = Source(List(1, 2, 3))
@ -16,7 +16,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
"Reverse Arrows in the Graph DSL" must { "Reverse Arrows in the Graph DSL" must {
"work from Inlets" in { "work from Inlets" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
s.inlet <~ source s.inlet <~ source
ClosedShape ClosedShape
@ -24,7 +24,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"work from SinkShape" in { "work from SinkShape" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
s <~ source s <~ source
ClosedShape ClosedShape
@ -33,7 +33,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
"work from Sink" in { "work from Sink" in {
val sub = TestSubscriber.manualProbe[Int] val sub = TestSubscriber.manualProbe[Int]
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
Sink(sub) <~ source Sink(sub) <~ source
ClosedShape ClosedShape
}).run() }).run()
@ -43,7 +43,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"not work from Outlets" in { "not work from Outlets" in {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val o: Outlet[Int] = b.add(source).outlet val o: Outlet[Int] = b.add(source).outlet
"o <~ source" shouldNot compile "o <~ source" shouldNot compile
sink <~ o sink <~ o
@ -52,7 +52,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"not work from SourceShape" in { "not work from SourceShape" in {
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
val o: SourceShape[Int] = b.add(source) val o: SourceShape[Int] = b.add(source)
"o <~ source" shouldNot compile "o <~ source" shouldNot compile
sink <~ o sink <~ o
@ -65,7 +65,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"work from FlowShape" in { "work from FlowShape" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
val f: FlowShape[Int, Int] = b.add(Flow[Int]) val f: FlowShape[Int, Int] = b.add(Flow[Int])
f <~ source f <~ source
@ -75,7 +75,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"work from UniformFanInShape" in { "work from UniformFanInShape" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
val f: UniformFanInShape[Int, Int] = b.add(Merge[Int](1)) val f: UniformFanInShape[Int, Int] = b.add(Merge[Int](1))
f <~ source f <~ source
@ -85,7 +85,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"work from UniformFanOutShape" in { "work from UniformFanOutShape" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
val f: UniformFanOutShape[Int, Int] = b.add(Broadcast[Int](1)) val f: UniformFanOutShape[Int, Int] = b.add(Broadcast[Int](1))
f <~ source f <~ source
@ -95,7 +95,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"work towards Outlets" in { "work towards Outlets" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
val o: Outlet[Int] = b.add(source).outlet val o: Outlet[Int] = b.add(source).outlet
s <~ o s <~ o
@ -104,7 +104,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"work towards SourceShape" in { "work towards SourceShape" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
val o: SourceShape[Int] = b.add(source) val o: SourceShape[Int] = b.add(source)
s <~ o s <~ o
@ -113,7 +113,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"work towards Source" in { "work towards Source" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
s <~ source s <~ source
ClosedShape ClosedShape
@ -121,7 +121,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"work towards FlowShape" in { "work towards FlowShape" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
val f: FlowShape[Int, Int] = b.add(Flow[Int]) val f: FlowShape[Int, Int] = b.add(Flow[Int])
s <~ f s <~ f
@ -131,7 +131,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"work towards UniformFanInShape" in { "work towards UniformFanInShape" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
val f: UniformFanInShape[Int, Int] = b.add(Merge[Int](1)) val f: UniformFanInShape[Int, Int] = b.add(Merge[Int](1))
s <~ f s <~ f
@ -141,7 +141,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"fail towards already full UniformFanInShape" in { "fail towards already full UniformFanInShape" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
val f: UniformFanInShape[Int, Int] = b.add(Merge[Int](1)) val f: UniformFanInShape[Int, Int] = b.add(Merge[Int](1))
val src = b.add(source) val src = b.add(source)
@ -152,7 +152,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"work towards UniformFanOutShape" in { "work towards UniformFanOutShape" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
val f: UniformFanOutShape[Int, Int] = b.add(Broadcast[Int](1)) val f: UniformFanOutShape[Int, Int] = b.add(Broadcast[Int](1))
s <~ f s <~ f
@ -162,7 +162,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"fail towards already full UniformFanOutShape" in { "fail towards already full UniformFanOutShape" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
val f: UniformFanOutShape[Int, Int] = b.add(Broadcast[Int](1)) val f: UniformFanOutShape[Int, Int] = b.add(Broadcast[Int](1))
val src = b.add(source) val src = b.add(source)
@ -173,7 +173,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"work across a Flow" in { "work across a Flow" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
s <~ Flow[Int] <~ source s <~ Flow[Int] <~ source
ClosedShape ClosedShape
@ -181,7 +181,7 @@ class ReverseArrowSpec extends AkkaSpec with ConversionCheckedTripleEquals {
} }
"work across a FlowShape" in { "work across a FlowShape" in {
Await.result(RunnableGraph.fromGraph(FlowGraph.create(sink) { implicit b Await.result(RunnableGraph.fromGraph(GraphDSL.create(sink) { implicit b
s s
s <~ b.add(Flow[Int]) <~ source s <~ b.add(Flow[Int]) <~ source
ClosedShape ClosedShape

View file

@ -9,7 +9,7 @@ import akka.stream.testkit._
class SinkSpec extends AkkaSpec { class SinkSpec extends AkkaSpec {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
implicit val mat = ActorMaterializer() implicit val mat = ActorMaterializer()
@ -17,7 +17,7 @@ class SinkSpec extends AkkaSpec {
"be composable without importing modules" in { "be composable without importing modules" in {
val probes = Array.fill(3)(TestSubscriber.manualProbe[Int]) val probes = Array.fill(3)(TestSubscriber.manualProbe[Int])
val sink = Sink.fromGraph(FlowGraph.create() { implicit b val sink = Sink.fromGraph(GraphDSL.create() { implicit b
val bcast = b.add(Broadcast[Int](3)) val bcast = b.add(Broadcast[Int](3))
for (i 0 to 2) bcast.out(i).filter(_ == i) ~> Sink(probes(i)) for (i 0 to 2) bcast.out(i).filter(_ == i) ~> Sink(probes(i))
SinkShape(bcast.in) SinkShape(bcast.in)
@ -34,7 +34,7 @@ class SinkSpec extends AkkaSpec {
"be composable with importing 1 module" in { "be composable with importing 1 module" in {
val probes = Array.fill(3)(TestSubscriber.manualProbe[Int]) val probes = Array.fill(3)(TestSubscriber.manualProbe[Int])
val sink = Sink.fromGraph(FlowGraph.create(Sink(probes(0))) { implicit b val sink = Sink.fromGraph(GraphDSL.create(Sink(probes(0))) { implicit b
s0 s0
val bcast = b.add(Broadcast[Int](3)) val bcast = b.add(Broadcast[Int](3))
bcast.out(0) ~> Flow[Int].filter(_ == 0) ~> s0.inlet bcast.out(0) ~> Flow[Int].filter(_ == 0) ~> s0.inlet
@ -53,7 +53,7 @@ class SinkSpec extends AkkaSpec {
"be composable with importing 2 modules" in { "be composable with importing 2 modules" in {
val probes = Array.fill(3)(TestSubscriber.manualProbe[Int]) val probes = Array.fill(3)(TestSubscriber.manualProbe[Int])
val sink = Sink.fromGraph(FlowGraph.create(Sink(probes(0)), Sink(probes(1)))(List(_, _)) { implicit b val sink = Sink.fromGraph(GraphDSL.create(Sink(probes(0)), Sink(probes(1)))(List(_, _)) { implicit b
(s0, s1) (s0, s1)
val bcast = b.add(Broadcast[Int](3)) val bcast = b.add(Broadcast[Int](3))
bcast.out(0).filter(_ == 0) ~> s0.inlet bcast.out(0).filter(_ == 0) ~> s0.inlet
@ -73,7 +73,7 @@ class SinkSpec extends AkkaSpec {
"be composable with importing 3 modules" in { "be composable with importing 3 modules" in {
val probes = Array.fill(3)(TestSubscriber.manualProbe[Int]) val probes = Array.fill(3)(TestSubscriber.manualProbe[Int])
val sink = Sink.fromGraph(FlowGraph.create(Sink(probes(0)), Sink(probes(1)), Sink(probes(2)))(List(_, _, _)) { implicit b val sink = Sink.fromGraph(GraphDSL.create(Sink(probes(0)), Sink(probes(1)), Sink(probes(2)))(List(_, _, _)) { implicit b
(s0, s1, s2) (s0, s1, s2)
val bcast = b.add(Broadcast[Int](3)) val bcast = b.add(Broadcast[Int](3))
bcast.out(0).filter(_ == 0) ~> s0.inlet bcast.out(0).filter(_ == 0) ~> s0.inlet

View file

@ -136,9 +136,9 @@ class SourceSpec extends AkkaSpec {
val source = Source.subscriber[Int] val source = Source.subscriber[Int]
val out = TestSubscriber.manualProbe[Int] val out = TestSubscriber.manualProbe[Int]
val s = Source.fromGraph(FlowGraph.create(source, source, source, source, source)(Seq(_, _, _, _, _)) { implicit b val s = Source.fromGraph(GraphDSL.create(source, source, source, source, source)(Seq(_, _, _, _, _)) { implicit b
(i0, i1, i2, i3, i4) (i0, i1, i2, i3, i4)
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val m = b.add(Merge[Int](5)) val m = b.add(Merge[Int](5))
i0.outlet ~> m.in(0) i0.outlet ~> m.in(0)
i1.outlet ~> m.in(1) i1.outlet ~> m.in(1)
@ -212,7 +212,7 @@ class SourceSpec extends AkkaSpec {
"Repeat Source" must { "Repeat Source" must {
"repeat as long as it takes" in { "repeat as long as it takes" in {
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val result = Await.result(Source.repeat(42).grouped(10000).runWith(Sink.head), 1.second) val result = Await.result(Source.repeat(42).grouped(10000).runWith(Sink.head), 1.second)
result.size should ===(10000) result.size should ===(10000)
result.toSet should ===(Set(42)) result.toSet should ===(Set(42))

View file

@ -67,8 +67,8 @@ class TickSourceSpec extends AkkaSpec {
"be usable with zip for a simple form of rate limiting" in { "be usable with zip for a simple form of rate limiting" in {
val c = TestSubscriber.manualProbe[Int]() val c = TestSubscriber.manualProbe[Int]()
RunnableGraph.fromGraph(FlowGraph.create() { implicit b RunnableGraph.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val zip = b.add(Zip[Int, String]()) val zip = b.add(Zip[Int, String]())
Source(1 to 100) ~> zip.in0 Source(1 to 100) ~> zip.in0
Source.tick(1.second, 1.second, "tick") ~> zip.in1 Source.tick(1.second, 1.second, "tick") ~> zip.in1

View file

@ -9,34 +9,34 @@ import akka.japi.function
private[stream] abstract class GraphCreate { private[stream] abstract class GraphCreate {
/** /**
* Creates a new [[Graph]] of the given [[Shape]] by passing a [[FlowGraph.Builder]] to the given create function. * Creates a new [[Graph]] of the given [[Shape]] by passing a [[GraphDSL.Builder]] to the given create function.
*/ */
def create[S <: Shape](block: function.Function[FlowGraph.Builder[Unit], S]): Graph[S, Unit] = def create[S <: Shape](block: function.Function[GraphDSL.Builder[Unit], S]): Graph[S, Unit] =
scaladsl.FlowGraph.create() { b ⇒ block.apply(b.asJava) } scaladsl.GraphDSL.create() { b ⇒ block.apply(b.asJava) }
/** /**
* Creates a new [[Graph]] by importing the given graph `g1` and its [[Shape]] * Creates a new [[Graph]] by importing the given graph `g1` and its [[Shape]]
* along with the [[FlowGraph.Builder]] to the given create function. * along with the [[GraphDSL.Builder]] to the given create function.
*/ */
def create[S1 <: Shape, S <: Shape, M](g1: Graph[S1, M], def create[S1 <: Shape, S <: Shape, M](g1: Graph[S1, M],
block: function.Function2[FlowGraph.Builder[M], S1, S]): Graph[S, M] = block: function.Function2[GraphDSL.Builder[M], S1, S]): Graph[S, M] =
scaladsl.FlowGraph.create(g1) { b ⇒ s => block.apply(b.asJava, s) } scaladsl.GraphDSL.create(g1) { b ⇒ s => block.apply(b.asJava, s) }
/** /**
* Creates a new [[Graph]] by importing the given graphs and passing their [[Shape]]s * Creates a new [[Graph]] by importing the given graphs and passing their [[Shape]]s
* along with the [[FlowGraph.Builder]] to the given create function. * along with the [[GraphDSL.Builder]] to the given create function.
*/ */
def create[S1 <: Shape, S2 <: Shape, S <: Shape, M1, M2, M](g1: Graph[S1, M1], g2: Graph[S2, M2], combineMat: function.Function2[M1, M2, M], def create[S1 <: Shape, S2 <: Shape, S <: Shape, M1, M2, M](g1: Graph[S1, M1], g2: Graph[S2, M2], combineMat: function.Function2[M1, M2, M],
block: function.Function3[FlowGraph.Builder[M], S1, S2, S]): Graph[S, M] = block: function.Function3[GraphDSL.Builder[M], S1, S2, S]): Graph[S, M] =
scaladsl.FlowGraph.create(g1, g2)(combineMat.apply) { b => (s1, s2) => block.apply(b.asJava, s1, s2) } scaladsl.GraphDSL.create(g1, g2)(combineMat.apply) { b => (s1, s2) => block.apply(b.asJava, s1, s2) }
[3..21#/** [3..21#/**
* Creates a new [[Graph]] by importing the given graphs and passing their [[Shape]]s * Creates a new [[Graph]] by importing the given graphs and passing their [[Shape]]s
* along with the [[FlowGraph.Builder]] to the given create function. * along with the [[GraphDSL.Builder]] to the given create function.
*/ */
def create1[[#S1 <: Shape#], S <: Shape, [#M1#], M]([#g1: Graph[S1, M1]#], combineMat: function.Function1[[#M1#], M], def create1[[#S1 <: Shape#], S <: Shape, [#M1#], M]([#g1: Graph[S1, M1]#], combineMat: function.Function1[[#M1#], M],
block: function.Function2[FlowGraph.Builder[M], [#S1#], S]): Graph[S, M] = block: function.Function2[GraphDSL.Builder[M], [#S1#], S]): Graph[S, M] =
scaladsl.FlowGraph.create([#g1#])(combineMat.apply) { b => ([#s1#]) => block.apply(b.asJava, [#s1#]) }# scaladsl.GraphDSL.create([#g1#])(combineMat.apply) { b => ([#s1#]) => block.apply(b.asJava, [#s1#]) }#
] ]
} }

View file

@ -9,10 +9,10 @@ import akka.stream.{ Graph, Attributes, Shape }
trait GraphApply { trait GraphApply {
/** /**
* Creates a new [[Graph]] by passing a [[FlowGraph.Builder]] to the given create function. * Creates a new [[Graph]] by passing a [[GraphDSL.Builder]] to the given create function.
*/ */
def create[S <: Shape]()(buildBlock: FlowGraph.Builder[Unit] ⇒ S): Graph[S, Unit] = { def create[S <: Shape]()(buildBlock: GraphDSL.Builder[Unit] ⇒ S): Graph[S, Unit] = {
val builder = new FlowGraph.Builder val builder = new GraphDSL.Builder
val s = buildBlock(builder) val s = buildBlock(builder)
val mod = builder.module.nest().replaceShape(s) val mod = builder.module.nest().replaceShape(s)
@ -21,10 +21,10 @@ trait GraphApply {
/** /**
* Creates a new [[Graph]] by importing the given graph `g1` and passing its [[Shape]] * Creates a new [[Graph]] by importing the given graph `g1` and passing its [[Shape]]
* along with the [[FlowGraph.Builder]] to the given create function. * along with the [[GraphDSL.Builder]] to the given create function.
*/ */
def create[S <: Shape, Mat](g1: Graph[Shape, Mat])(buildBlock: FlowGraph.Builder[Mat] ⇒ (g1.Shape) ⇒ S): Graph[S, Mat] = { def create[S <: Shape, Mat](g1: Graph[Shape, Mat])(buildBlock: GraphDSL.Builder[Mat] ⇒ (g1.Shape) ⇒ S): Graph[S, Mat] = {
val builder = new FlowGraph.Builder val builder = new GraphDSL.Builder
val s1 = builder.add(g1) val s1 = builder.add(g1)
val s = buildBlock(builder)(s1) val s = buildBlock(builder)(s1)
val mod = builder.module.nest().replaceShape(s) val mod = builder.module.nest().replaceShape(s)
@ -37,10 +37,10 @@ trait GraphApply {
/** /**
* Creates a new [[Graph]] by importing the given graphs and passing their [[Shape]]s * Creates a new [[Graph]] by importing the given graphs and passing their [[Shape]]s
* along with the [[FlowGraph.Builder]] to the given create function. * along with the [[GraphDSL.Builder]] to the given create function.
*/ */
def create[S <: Shape, Mat, [#M1#]]([#g1: Graph[Shape, M1]#])(combineMat: ([#M1#]) ⇒ Mat)(buildBlock: FlowGraph.Builder[Mat] ⇒ ([#g1.Shape#]) ⇒ S): Graph[S, Mat] = { def create[S <: Shape, Mat, [#M1#]]([#g1: Graph[Shape, M1]#])(combineMat: ([#M1#]) ⇒ Mat)(buildBlock: GraphDSL.Builder[Mat] ⇒ ([#g1.Shape#]) ⇒ S): Graph[S, Mat] = {
val builder = new FlowGraph.Builder val builder = new GraphDSL.Builder
val curried = combineMat.curried val curried = combineMat.curried
val s##1 = builder.add(g##1, (m##1: M##1) ⇒ curried(m##1)) val s##1 = builder.add(g##1, (m##1: M##1) ⇒ curried(m##1))
[2..#val s1 = builder.add(g1, (f: M1 ⇒ Any, m1: M1) ⇒ f(m1))# [2..#val s1 = builder.add(g1, (f: M1 ⇒ Any, m1: M1) ⇒ f(m1))#

View file

@ -10,7 +10,7 @@ import akka.japi.function
/** /**
* Holds attributes which can be used to alter [[akka.stream.scaladsl.Flow]] / [[akka.stream.javadsl.Flow]] * Holds attributes which can be used to alter [[akka.stream.scaladsl.Flow]] / [[akka.stream.javadsl.Flow]]
* or [[akka.stream.scaladsl.FlowGraph]] / [[akka.stream.javadsl.FlowGraph]] materialization. * or [[akka.stream.scaladsl.GraphDSL]] / [[akka.stream.javadsl.GraphDSL]] materialization.
* *
* Note that more attributes for the [[ActorMaterializer]] are defined in [[ActorAttributes]]. * Note that more attributes for the [[ActorMaterializer]] are defined in [[ActorAttributes]].
*/ */

View file

@ -152,7 +152,7 @@ object SslTls {
*/ */
object SslTlsPlacebo { object SslTlsPlacebo {
val forScala: scaladsl.BidiFlow[SslTlsOutbound, ByteString, ByteString, SessionBytes, Unit] = val forScala: scaladsl.BidiFlow[SslTlsOutbound, ByteString, ByteString, SessionBytes, Unit] =
scaladsl.BidiFlow.fromGraph(scaladsl.FlowGraph.create() { implicit b scaladsl.BidiFlow.fromGraph(scaladsl.GraphDSL.create() { implicit b
// this constructs a session for (invalid) protocol SSL_NULL_WITH_NULL_NULL // this constructs a session for (invalid) protocol SSL_NULL_WITH_NULL_NULL
val session = SSLContext.getDefault.createSSLEngine.getSession val session = SSLContext.getDefault.createSSLEngine.getSession
val top = b.add(scaladsl.Flow[SslTlsOutbound].collect { case SendBytes(bytes) bytes }) val top = b.add(scaladsl.Flow[SslTlsOutbound].collect { case SendBytes(bytes) bytes })

View file

@ -964,9 +964,9 @@ final class Flow[-In, +Out, +Mat](delegate: scaladsl.Flow[In, Out, Mat]) extends
*/ */
def zipMat[T, M, M2](that: Graph[SourceShape[T], M], def zipMat[T, M, M2](that: Graph[SourceShape[T], M],
matF: function.Function2[Mat, M, M2]): javadsl.Flow[In, Out @uncheckedVariance Pair T, M2] = matF: function.Function2[Mat, M, M2]): javadsl.Flow[In, Out @uncheckedVariance Pair T, M2] =
this.viaMat(Flow.fromGraph(FlowGraph.create(that, this.viaMat(Flow.fromGraph(GraphDSL.create(that,
new function.Function2[FlowGraph.Builder[M], SourceShape[T], FlowShape[Out, Out @ uncheckedVariance Pair T]] { new function.Function2[GraphDSL.Builder[M], SourceShape[T], FlowShape[Out, Out @ uncheckedVariance Pair T]] {
def apply(b: FlowGraph.Builder[M], s: SourceShape[T]): FlowShape[Out, Out @uncheckedVariance Pair T] = { def apply(b: GraphDSL.Builder[M], s: SourceShape[T]): FlowShape[Out, Out @uncheckedVariance Pair T] = {
val zip: FanInShape2[Out, T, Out Pair T] = b.add(Zip.create[Out, T]) val zip: FanInShape2[Out, T, Out Pair T] = b.add(Zip.create[Out, T])
b.from(s).toInlet(zip.in1) b.from(s).toInlet(zip.in1)
FlowShape(zip.in0, zip.out) FlowShape(zip.in0, zip.out)

View file

@ -270,18 +270,18 @@ object Concat {
// flow graph // // flow graph //
object FlowGraph extends GraphCreate { object GraphDSL extends GraphCreate {
/** /**
* Start building a [[FlowGraph]]. * Start building a [[GraphDSL]].
* *
* The [[Builder]] is mutable and not thread-safe, * The [[Builder]] is mutable and not thread-safe,
* thus you should construct your Graph and then share the constructed immutable [[FlowGraph]]. * thus you should construct your Graph and then share the constructed immutable [[GraphDSL]].
*/ */
def builder[M](): Builder[M] = new Builder()(new scaladsl.FlowGraph.Builder[M]) def builder[M](): Builder[M] = new Builder()(new scaladsl.GraphDSL.Builder[M])
final class Builder[+Mat]()(private implicit val delegate: scaladsl.FlowGraph.Builder[Mat]) { self final class Builder[+Mat]()(private implicit val delegate: scaladsl.GraphDSL.Builder[Mat]) { self
import akka.stream.scaladsl.FlowGraph.Implicits._ import akka.stream.scaladsl.GraphDSL.Implicits._
/** /**
* Import a graph into this module, performing a deep copy, discarding its * Import a graph into this module, performing a deep copy, discarding its

View file

@ -116,7 +116,7 @@ final class BidiFlow[-I1, +O1, -I2, +O2, +Mat](private[stream] override val modu
* Turn this BidiFlow around by 180 degrees, logically flipping it upside down in a protocol stack. * Turn this BidiFlow around by 180 degrees, logically flipping it upside down in a protocol stack.
*/ */
def reversed: BidiFlow[I2, O2, I1, O1, Mat] = { def reversed: BidiFlow[I2, O2, I1, O1, Mat] = {
BidiFlow.fromGraph(FlowGraph.create(this) { implicit b BidiFlow.fromGraph(GraphDSL.create(this) { implicit b
reversed reversed
BidiShape(reversed.in2, reversed.out2, reversed.in1, reversed.out1) BidiShape(reversed.in2, reversed.out2, reversed.in1, reversed.out1)
}) })
@ -169,7 +169,7 @@ object BidiFlow {
def fromFlowsMat[I1, O1, I2, O2, M1, M2, M]( def fromFlowsMat[I1, O1, I2, O2, M1, M2, M](
flow1: Graph[FlowShape[I1, O1], M1], flow1: Graph[FlowShape[I1, O1], M1],
flow2: Graph[FlowShape[I2, O2], M2])(combine: (M1, M2) M): BidiFlow[I1, O1, I2, O2, M] = flow2: Graph[FlowShape[I2, O2], M2])(combine: (M1, M2) M): BidiFlow[I1, O1, I2, O2, M] =
fromGraph(FlowGraph.create(flow1, flow2)(combine) { fromGraph(GraphDSL.create(flow1, flow2)(combine) {
implicit b (f1, f2) BidiShape(f1.inlet, f1.outlet, f2.inlet, f2.outlet) implicit b (f1, f2) BidiShape(f1.inlet, f1.outlet, f2.inlet, f2.outlet)
}) })

View file

@ -285,7 +285,7 @@ object Flow {
* Helper to create `Flow` from a `Sink`and a `Source`. * Helper to create `Flow` from a `Sink`and a `Source`.
*/ */
def fromSinkAndSourceMat[I, O, M1, M2, M](sink: Graph[SinkShape[I], M1], source: Graph[SourceShape[O], M2])(f: (M1, M2) M): Flow[I, O, M] = def fromSinkAndSourceMat[I, O, M1, M2, M](sink: Graph[SinkShape[I], M1], source: Graph[SourceShape[O], M2])(f: (M1, M2) M): Flow[I, O, M] =
fromGraph(FlowGraph.create(sink, source)(f) { implicit b (in, out) FlowShape(in.inlet, out.outlet) }) fromGraph(GraphDSL.create(sink, source)(f) { implicit b (in, out) FlowShape(in.inlet, out.outlet) })
} }
object RunnableGraph { object RunnableGraph {
@ -1192,9 +1192,9 @@ trait FlowOps[+Out, +Mat] {
* @see [[#zip]]. * @see [[#zip]].
*/ */
def zipMat[U, Mat2, Mat3](that: Graph[SourceShape[U], Mat2])(matF: (Mat, Mat2) Mat3): Repr[(Out, U), Mat3] = def zipMat[U, Mat2, Mat3](that: Graph[SourceShape[U], Mat2])(matF: (Mat, Mat2) Mat3): Repr[(Out, U), Mat3] =
this.viaMat(FlowGraph.create(that) { implicit b this.viaMat(GraphDSL.create(that) { implicit b
r r
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val zip = b.add(Zip[Out, U]()) val zip = b.add(Zip[Out, U]())
r ~> zip.in1 r ~> zip.in1
FlowShape(zip.in0, zip.out) FlowShape(zip.in0, zip.out)
@ -1222,9 +1222,9 @@ trait FlowOps[+Out, +Mat] {
* @see [[#zipWith]]. * @see [[#zipWith]].
*/ */
def zipWithMat[Out2, Out3, Mat2, Mat3](that: Graph[SourceShape[Out2], Mat2])(combine: (Out, Out2) Out3)(matF: (Mat, Mat2) Mat3): Repr[Out3, Mat3] = def zipWithMat[Out2, Out3, Mat2, Mat3](that: Graph[SourceShape[Out2], Mat2])(combine: (Out, Out2) Out3)(matF: (Mat, Mat2) Mat3): Repr[Out3, Mat3] =
this.viaMat(FlowGraph.create(that) { implicit b this.viaMat(GraphDSL.create(that) { implicit b
r r
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val zip = b.add(ZipWith[Out, Out2, Out3](combine)) val zip = b.add(ZipWith[Out, Out2, Out3](combine))
r ~> zip.in1 r ~> zip.in1
FlowShape(zip.in0, zip.out) FlowShape(zip.in0, zip.out)
@ -1252,9 +1252,9 @@ trait FlowOps[+Out, +Mat] {
* @see [[#merge]]. * @see [[#merge]].
*/ */
def mergeMat[U >: Out, Mat2, Mat3](that: Graph[SourceShape[U], Mat2])(matF: (Mat, Mat2) Mat3): Repr[U, Mat3] = def mergeMat[U >: Out, Mat2, Mat3](that: Graph[SourceShape[U], Mat2])(matF: (Mat, Mat2) Mat3): Repr[U, Mat3] =
this.viaMat(FlowGraph.create(that) { implicit b this.viaMat(GraphDSL.create(that) { implicit b
r r
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val merge = b.add(Merge[U](2)) val merge = b.add(Merge[U](2))
r ~> merge.in(1) r ~> merge.in(1)
FlowShape(merge.in(0), merge.out) FlowShape(merge.in(0), merge.out)
@ -1294,9 +1294,9 @@ trait FlowOps[+Out, +Mat] {
* @see [[#concat]]. * @see [[#concat]].
*/ */
def concatMat[U >: Out, Mat2, Mat3](that: Graph[SourceShape[U], Mat2])(matF: (Mat, Mat2) Mat3): Repr[U, Mat3] = def concatMat[U >: Out, Mat2, Mat3](that: Graph[SourceShape[U], Mat2])(matF: (Mat, Mat2) Mat3): Repr[U, Mat3] =
this.viaMat(FlowGraph.create(that) { implicit b this.viaMat(GraphDSL.create(that) { implicit b
r r
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val merge = b.add(Concat[U]()) val merge = b.add(Concat[U]())
r ~> merge.in(1) r ~> merge.in(1)
FlowShape(merge.in(0), merge.out) FlowShape(merge.in(0), merge.out)
@ -1332,9 +1332,9 @@ trait FlowOps[+Out, +Mat] {
* @see [[#alsoTo]] * @see [[#alsoTo]]
*/ */
def alsoToMat[Mat2, Mat3](that: Graph[SinkShape[Out], Mat2])(matF: (Mat, Mat2) Mat3): Repr[Out, Mat3] = def alsoToMat[Mat2, Mat3](that: Graph[SinkShape[Out], Mat2])(matF: (Mat, Mat2) Mat3): Repr[Out, Mat3] =
this.viaMat(FlowGraph.create(that) { implicit b this.viaMat(GraphDSL.create(that) { implicit b
r r
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val bcast = b.add(Broadcast[Out](2)) val bcast = b.add(Broadcast[Out](2))
bcast.out(1) ~> r bcast.out(1) ~> r
FlowShape(bcast.in, bcast.out(0)) FlowShape(bcast.in, bcast.out(0))

View file

@ -555,7 +555,7 @@ class Concat[T](inputCount: Int) extends GraphStage[UniformFanInShape[T, T]] {
} }
} }
object FlowGraph extends GraphApply { object GraphDSL extends GraphApply {
class Builder[+M] private[stream] () { class Builder[+M] private[stream] () {
private var moduleInProgress: Module = EmptyModule private var moduleInProgress: Module = EmptyModule
@ -563,7 +563,7 @@ object FlowGraph extends GraphApply {
/** /**
* INTERNAL API * INTERNAL API
*/ */
private[FlowGraph] def addEdge[T, U >: T](from: Outlet[T], to: Inlet[U]): Unit = private[GraphDSL] def addEdge[T, U >: T](from: Outlet[T], to: Inlet[U]): Unit =
moduleInProgress = moduleInProgress.wire(from, to) moduleInProgress = moduleInProgress.wire(from, to)
/** /**
@ -634,7 +634,7 @@ object FlowGraph extends GraphApply {
private[stream] def module: Module = moduleInProgress private[stream] def module: Module = moduleInProgress
/** Converts this Scala DSL element to it's Java DSL counterpart. */ /** Converts this Scala DSL element to it's Java DSL counterpart. */
def asJava: javadsl.FlowGraph.Builder[M] = new javadsl.FlowGraph.Builder()(this) def asJava: javadsl.GraphDSL.Builder[M] = new javadsl.GraphDSL.Builder()(this)
} }
object Implicits { object Implicits {

View file

@ -154,8 +154,8 @@ object Sink {
*/ */
def combine[T, U](first: Sink[U, _], second: Sink[U, _], rest: Sink[U, _]*)(strategy: Int Graph[UniformFanOutShape[T, U], Unit]): Sink[T, Unit] = def combine[T, U](first: Sink[U, _], second: Sink[U, _], rest: Sink[U, _]*)(strategy: Int Graph[UniformFanOutShape[T, U], Unit]): Sink[T, Unit] =
Sink.fromGraph(FlowGraph.create() { implicit b Sink.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val d = b.add(strategy(rest.size + 2)) val d = b.add(strategy(rest.size + 2))
d.out(0) ~> first d.out(0) ~> first
d.out(1) ~> second d.out(1) ~> second

View file

@ -119,8 +119,8 @@ final class Source[+Out, +Mat](private[stream] override val module: Module)
* Combines several sources with fun-in strategy like `Merge` or `Concat` and returns `Source`. * Combines several sources with fun-in strategy like `Merge` or `Concat` and returns `Source`.
*/ */
def combine[T, U](first: Source[T, _], second: Source[T, _], rest: Source[T, _]*)(strategy: Int Graph[UniformFanInShape[T, U], Unit]): Source[U, Unit] = def combine[T, U](first: Source[T, _], second: Source[T, _], rest: Source[T, _]*)(strategy: Int Graph[UniformFanInShape[T, U], Unit]): Source[U, Unit] =
Source.fromGraph(FlowGraph.create() { implicit b Source.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val c = b.add(strategy(rest.size + 2)) val c = b.add(strategy(rest.size + 2))
first ~> c.in(0) first ~> c.in(0)
second ~> c.in(1) second ~> c.in(1)
@ -330,8 +330,8 @@ object Source {
* Combines several sources with fun-in strategy like `Merge` or `Concat` and returns `Source`. * Combines several sources with fun-in strategy like `Merge` or `Concat` and returns `Source`.
*/ */
def combine[T, U](first: Source[T, _], second: Source[T, _], rest: Source[T, _]*)(strategy: Int Graph[UniformFanInShape[T, U], Unit]): Source[U, Unit] = def combine[T, U](first: Source[T, _], second: Source[T, _], rest: Source[T, _]*)(strategy: Int Graph[UniformFanInShape[T, U], Unit]): Source[U, Unit] =
Source.fromGraph(FlowGraph.create() { implicit b Source.fromGraph(GraphDSL.create() { implicit b
import FlowGraph.Implicits._ import GraphDSL.Implicits._
val c = b.add(strategy(rest.size + 2)) val c = b.add(strategy(rest.size + 2))
first ~> c.in(0) first ~> c.in(0)
second ~> c.in(1) second ~> c.in(1)

View file

@ -26,7 +26,7 @@ package akka.stream
* *
* You can create your `Source`, `Flow` and `Sink` in any order and then wire them together before * You can create your `Source`, `Flow` and `Sink` in any order and then wire them together before
* they are materialized by connecting them using [[Flow#via]] and [[Flow#to]], or connecting them into a * they are materialized by connecting them using [[Flow#via]] and [[Flow#to]], or connecting them into a
* [[FlowGraph]] with fan-in and fan-out elements. * [[GraphDSL]] with fan-in and fan-out elements.
* *
* See <a href="https://github.com/reactive-streams/reactive-streams/">Reactive Streams</a> for * See <a href="https://github.com/reactive-streams/reactive-streams/">Reactive Streams</a> for
* details on [[org.reactivestreams.Publisher]] and [[org.reactivestreams.Subscriber]]. * details on [[org.reactivestreams.Publisher]] and [[org.reactivestreams.Subscriber]].