Update image links (#24031)

This commit is contained in:
Jonas Lantto 2017-11-22 16:09:42 +01:00 committed by Johan Andrén
parent 3e74ca739e
commit 836f9612b8
16 changed files with 51 additions and 51 deletions

View file

@ -377,7 +377,7 @@ The implementations shown above are the defaults provided by the @scala[`Actor`
<a id="actor-lifecycle"></a> <a id="actor-lifecycle"></a>
### Actor Lifecycle ### Actor Lifecycle
![actor_lifecycle.png](../images/actor_lifecycle.png) ![actor_lifecycle.png](./images/actor_lifecycle.png)
A path in an actor system represents a "place" which might be occupied A path in an actor system represents a "place" which might be occupied
by a living actor. Initially (apart from system initialized actors) a path is by a living actor. Initially (apart from system initialized actors) a path is

View file

@ -82,7 +82,7 @@ but unreachability across different data centers don't influence the progress of
within a data center. Nodes can be added and removed also when there are network partitions between within a data center. Nodes can be added and removed also when there are network partitions between
data centers, which is impossible if nodes are not grouped into data centers. data centers, which is impossible if nodes are not grouped into data centers.
![cluster-dc.png](../images/cluster-dc.png) ![cluster-dc.png](./images/cluster-dc.png)
User actions like joining, leaving, and downing can be sent to any node in the cluster, User actions like joining, leaving, and downing can be sent to any node in the cluster,
not only to the nodes in the data center of the node. Seed nodes are also global. not only to the nodes in the data center of the node. Seed nodes are also global.

View file

@ -557,7 +557,7 @@ order to account for network issues that sometimes occur on such platforms.
The following chart illustrates how *phi* increase with increasing time since the The following chart illustrates how *phi* increase with increasing time since the
previous heartbeat. previous heartbeat.
![phi1.png](../images/phi1.png) ![phi1.png](./images/phi1.png)
Phi is calculated from the mean and standard deviation of historical Phi is calculated from the mean and standard deviation of historical
inter arrival times. The previous chart is an example for standard deviation inter arrival times. The previous chart is an example for standard deviation
@ -565,7 +565,7 @@ of 200 ms. If the heartbeats arrive with less deviation the curve becomes steepe
i.e. it is possible to determine failure more quickly. The curve looks like this for i.e. it is possible to determine failure more quickly. The curve looks like this for
a standard deviation of 100 ms. a standard deviation of 100 ms.
![phi2.png](../images/phi2.png) ![phi2.png](./images/phi2.png)
To be able to survive sudden abnormalities, such as garbage collection pauses and To be able to survive sudden abnormalities, such as garbage collection pauses and
transient network failures the failure detector is configured with a margin, transient network failures the failure detector is configured with a margin,
@ -574,7 +574,7 @@ adjust the [configuration](#cluster-configuration) of this depending on your env
This is how the curve looks like for `acceptable-heartbeat-pause` configured to This is how the curve looks like for `acceptable-heartbeat-pause` configured to
3 seconds. 3 seconds.
![phi3.png](../images/phi3.png) ![phi3.png](./images/phi3.png)
Death watch uses the cluster failure detector for nodes in the cluster, i.e. it detects Death watch uses the cluster failure detector for nodes in the cluster, i.e. it detects
network failures and JVM crashes, in addition to graceful termination of watched network failures and JVM crashes, in addition to graceful termination of watched

View file

@ -59,7 +59,7 @@ The Akka library provides an implementation of a circuit breaker called
- These are executed in the `ExecutionContext` provided. - These are executed in the `ExecutionContext` provided.
![circuit-breaker-states.png](../../images/circuit-breaker-states.png) ![circuit-breaker-states.png](../images/circuit-breaker-states.png)
## Examples ## Examples

View file

@ -259,11 +259,11 @@ members in quorum decisions.
#### State Diagram for the Member States (`akka.cluster.allow-weakly-up-members=off`) #### State Diagram for the Member States (`akka.cluster.allow-weakly-up-members=off`)
![member-states.png](../../images/member-states.png) ![member-states.png](../images/member-states.png)
#### State Diagram for the Member States (`akka.cluster.allow-weakly-up-members=on`) #### State Diagram for the Member States (`akka.cluster.allow-weakly-up-members=on`)
![member-states-weakly-up.png](../../images/member-states-weakly-up.png) ![member-states-weakly-up.png](../images/member-states-weakly-up.png)
#### Member States #### Member States

View file

@ -291,7 +291,7 @@ and then you can apply the proposed solutions as explained below.
@@@ @@@
![dispatcher-behaviour-on-bad-code.png](../images/dispatcher-behaviour-on-bad-code.png) ![dispatcher-behaviour-on-bad-code.png](./images/dispatcher-behaviour-on-bad-code.png)
In the above example we put the code under load by sending hundreds of messages to the blocking actor In the above example we put the code under load by sending hundreds of messages to the blocking actor
which causes threads of the default dispatcher to be blocked. which causes threads of the default dispatcher to be blocked.
@ -334,7 +334,7 @@ Java
The thread pool behaviour is shown in the below diagram. The thread pool behaviour is shown in the below diagram.
![dispatcher-behaviour-on-good-code.png](../images/dispatcher-behaviour-on-good-code.png) ![dispatcher-behaviour-on-good-code.png](./images/dispatcher-behaviour-on-good-code.png)
Messages sent to `SeparateDispatcherFutureActor` and `PrintActor` are easily handled by the default dispatcher - the Messages sent to `SeparateDispatcherFutureActor` and `PrintActor` are easily handled by the default dispatcher - the
green lines, which represent the actual execution. green lines, which represent the actual execution.

View file

@ -2,7 +2,7 @@
<a id="fault-tolerance-sample"></a> <a id="fault-tolerance-sample"></a>
# Diagrams of the Fault Tolerance Sample # Diagrams of the Fault Tolerance Sample
![faulttolerancesample-normal-flow.png](../images/faulttolerancesample-normal-flow.png) ![faulttolerancesample-normal-flow.png](./images/faulttolerancesample-normal-flow.png)
*The above diagram illustrates the normal message flow.* *The above diagram illustrates the normal message flow.*
@ -15,7 +15,7 @@
|3, 4, 5 | When receiving `Do` the `Worker` tells the `CounterService` to increment the counter, three times. The `Increment` message is forwarded to the `Counter`, which updates its counter variable and sends current value to the `Storage`.| |3, 4, 5 | When receiving `Do` the `Worker` tells the `CounterService` to increment the counter, three times. The `Increment` message is forwarded to the `Counter`, which updates its counter variable and sends current value to the `Storage`.|
|6, 7 | The `Worker` asks the `CounterService` of current value of the counter and pipes the result back to the `Listener`. | |6, 7 | The `Worker` asks the `CounterService` of current value of the counter and pipes the result back to the `Listener`. |
![faulttolerancesample-failure-flow.png](../images/faulttolerancesample-failure-flow.png) ![faulttolerancesample-failure-flow.png](./images/faulttolerancesample-failure-flow.png)
*The above diagram illustrates what happens in case of storage failure.* *The above diagram illustrates what happens in case of storage failure.*

View file

@ -23,7 +23,7 @@ test nodes)
This is a schematic overview of the test conductor. This is a schematic overview of the test conductor.
![akka-remote-testconductor.png](../images/akka-remote-testconductor.png) ![akka-remote-testconductor.png](./images/akka-remote-testconductor.png)
The test conductor server is responsible for coordinating barriers and sending commands to the test conductor The test conductor server is responsible for coordinating barriers and sending commands to the test conductor
clients that act upon them, e.g. throttling network traffic to/from another client. More information on the clients that act upon them, e.g. throttling network traffic to/from another client. More information on the

View file

@ -110,7 +110,7 @@ datastore understands directly.
The below figure explains how the default serialization scheme works, and how it fits together with serializing the The below figure explains how the default serialization scheme works, and how it fits together with serializing the
user provided message itself, which we will from here on refer to as the `payload` (highlighted in yellow): user provided message itself, which we will from here on refer to as the `payload` (highlighted in yellow):
![persistent-message-envelope.png](../images/persistent-message-envelope.png) ![persistent-message-envelope.png](./images/persistent-message-envelope.png)
Akka Persistence provided serializers wrap the user payload in an envelope containing all persistence-relevant information. Akka Persistence provided serializers wrap the user payload in an envelope containing all persistence-relevant information.
**If the Journal uses provided Protobuf serializers for the wrapper types (e.g. PersistentRepr), then the payload will **If the Journal uses provided Protobuf serializers for the wrapper types (e.g. PersistentRepr), then the payload will
@ -249,7 +249,7 @@ representation of the message. This is one of the advantages of schema based ser
add the overhead of having to maintain the schema. When using serializers like this, no additional code change add the overhead of having to maintain the schema. When using serializers like this, no additional code change
(except renaming the field and method used during serialization) is needed to perform such evolution: (except renaming the field and method used during serialization) is needed to perform such evolution:
![persistence-serializer-rename.png](../images/persistence-serializer-rename.png) ![persistence-serializer-rename.png](./images/persistence-serializer-rename.png)
This is how such a rename would look in protobuf: This is how such a rename would look in protobuf:
@ -277,7 +277,7 @@ This approach is popular when your serialization format is something like JSON,
automatically by the serializer. You can do these kinds of "promotions" either manually (as shown in the example below) automatically by the serializer. You can do these kinds of "promotions" either manually (as shown in the example below)
or using a library like @scala[[Stamina](https://github.com/scalapenos/stamina)]@java[[Stamina](https://github.com/javapenos/stamina)] which helps to create those `V1->V2->V3->...->Vn` promotion chains without much boilerplate. or using a library like @scala[[Stamina](https://github.com/scalapenos/stamina)]@java[[Stamina](https://github.com/javapenos/stamina)] which helps to create those `V1->V2->V3->...->Vn` promotion chains without much boilerplate.
![persistence-manual-rename.png](../images/persistence-manual-rename.png) ![persistence-manual-rename.png](./images/persistence-manual-rename.png)
The following snippet showcases how one could apply renames if working with plain JSON (using @scala[`spray.json.JsObject`]@java[a `JsObject` as an example JSON representation]): The following snippet showcases how one could apply renames if working with plain JSON (using @scala[`spray.json.JsObject`]@java[a `JsObject` as an example JSON representation]):
@ -313,7 +313,7 @@ The problem of removing an event type from the domain model is not as much its r
for the recovery mechanisms that this entails. For example, a naive way of filtering out certain kinds of events from for the recovery mechanisms that this entails. For example, a naive way of filtering out certain kinds of events from
being delivered to a recovering `PersistentActor` is pretty simple, as one can simply filter them out in an @ref:[EventAdapter](persistence.md#event-adapters): being delivered to a recovering `PersistentActor` is pretty simple, as one can simply filter them out in an @ref:[EventAdapter](persistence.md#event-adapters):
![persistence-drop-event.png](../images/persistence-drop-event.png) ![persistence-drop-event.png](./images/persistence-drop-event.png)
The `EventAdapter` can drop old events (**O**) by emitting an empty `EventSeq`. The `EventAdapter` can drop old events (**O**) by emitting an empty `EventSeq`.
Other events can simply be passed through (**E**). Other events can simply be passed through (**E**).
@ -342,7 +342,7 @@ This can for example be implemented by using an `SerializerWithStringManifest`
(documented in depth in @ref:[Serializer with String Manifest](serialization.md#string-manifest-serializer)). By looking at the string manifest, the serializer can notice (documented in depth in @ref:[Serializer with String Manifest](serialization.md#string-manifest-serializer)). By looking at the string manifest, the serializer can notice
that the type is no longer needed, and skip the deserialization all-together: that the type is no longer needed, and skip the deserialization all-together:
![persistence-drop-event-serializer.png](../images/persistence-drop-event-serializer.png) ![persistence-drop-event-serializer.png](./images/persistence-drop-event-serializer.png)
The serializer is aware of the old event types that need to be skipped (**O**), and can skip deserializing them alltogether The serializer is aware of the old event types that need to be skipped (**O**), and can skip deserializing them alltogether
by simply returning a "tombstone" (**T**), which the EventAdapter converts into an empty EventSeq. by simply returning a "tombstone" (**T**), which the EventAdapter converts into an empty EventSeq.
@ -384,7 +384,7 @@ classes which very often may be less user-friendly yet highly optimised for thro
(like the classes generated by protobuf for example), it is possible to use a simple EventAdapter which maps between (like the classes generated by protobuf for example), it is possible to use a simple EventAdapter which maps between
these types in a 1:1 style as illustrated below: these types in a 1:1 style as illustrated below:
![persistence-detach-models.png](../images/persistence-detach-models.png) ![persistence-detach-models.png](./images/persistence-detach-models.png)
Domain events (**A**) are adapted to the data model events (**D**) by the `EventAdapter`. Domain events (**A**) are adapted to the data model events (**D**) by the `EventAdapter`.
The data model can be a format natively understood by the journal, such that it can store it more efficiently or The data model can be a format natively understood by the journal, such that it can store it more efficiently or
@ -478,7 +478,7 @@ The write side change is very simple, we simply persist `UserNameChanged` or `Us
on what the user actually intended to change (instead of the composite `UserDetailsChanged` that we had in version 1 on what the user actually intended to change (instead of the composite `UserDetailsChanged` that we had in version 1
of our model). of our model).
![persistence-event-adapter-1-n.png](../images/persistence-event-adapter-1-n.png) ![persistence-event-adapter-1-n.png](./images/persistence-event-adapter-1-n.png)
The `EventAdapter` splits the incoming event into smaller more fine grained events during recovery. The `EventAdapter` splits the incoming event into smaller more fine grained events during recovery.

View file

@ -491,7 +491,7 @@ order to account for network issues that sometimes occur on such platforms.
The following chart illustrates how *phi* increase with increasing time since the The following chart illustrates how *phi* increase with increasing time since the
previous heartbeat. previous heartbeat.
![phi1.png](../images/phi1.png) ![phi1.png](./images/phi1.png)
Phi is calculated from the mean and standard deviation of historical Phi is calculated from the mean and standard deviation of historical
inter arrival times. The previous chart is an example for standard deviation inter arrival times. The previous chart is an example for standard deviation
@ -499,7 +499,7 @@ of 200 ms. If the heartbeats arrive with less deviation the curve becomes steepe
i.e. it is possible to determine failure more quickly. The curve looks like this for i.e. it is possible to determine failure more quickly. The curve looks like this for
a standard deviation of 100 ms. a standard deviation of 100 ms.
![phi2.png](../images/phi2.png) ![phi2.png](./images/phi2.png)
To be able to survive sudden abnormalities, such as garbage collection pauses and To be able to survive sudden abnormalities, such as garbage collection pauses and
transient network failures the failure detector is configured with a margin, transient network failures the failure detector is configured with a margin,
@ -508,7 +508,7 @@ adjust the [Remote Configuration](#remote-configuration-artery) of this dependin
This is how the curve looks like for `acceptable-heartbeat-pause` configured to This is how the curve looks like for `acceptable-heartbeat-pause` configured to
3 seconds. 3 seconds.
![phi3.png](../images/phi3.png) ![phi3.png](./images/phi3.png)
## Serialization ## Serialization

View file

@ -253,7 +253,7 @@ Actor classes not included in the whitelist will not be allowed to be remote dep
## Lifecycle and Failure Recovery Model ## Lifecycle and Failure Recovery Model
![association_lifecycle.png](../images/association_lifecycle.png) ![association_lifecycle.png](./images/association_lifecycle.png)
Each link with a remote system can be in one of the four states as illustrated above. Before any communication Each link with a remote system can be in one of the four states as illustrated above. Before any communication
happens with a remote system at a given `Address` the state of the association is `Idle`. The first time a message happens with a remote system at a given `Address` the state of the association is `Idle`. The first time a message
@ -311,7 +311,7 @@ order to account for network issues that sometimes occur on such platforms.
The following chart illustrates how *phi* increase with increasing time since the The following chart illustrates how *phi* increase with increasing time since the
previous heartbeat. previous heartbeat.
![phi1.png](../images/phi1.png) ![phi1.png](./images/phi1.png)
Phi is calculated from the mean and standard deviation of historical Phi is calculated from the mean and standard deviation of historical
inter arrival times. The previous chart is an example for standard deviation inter arrival times. The previous chart is an example for standard deviation
@ -319,7 +319,7 @@ of 200 ms. If the heartbeats arrive with less deviation the curve becomes steepe
i.e. it is possible to determine failure more quickly. The curve looks like this for i.e. it is possible to determine failure more quickly. The curve looks like this for
a standard deviation of 100 ms. a standard deviation of 100 ms.
![phi2.png](../images/phi2.png) ![phi2.png](./images/phi2.png)
To be able to survive sudden abnormalities, such as garbage collection pauses and To be able to survive sudden abnormalities, such as garbage collection pauses and
transient network failures the failure detector is configured with a margin, transient network failures the failure detector is configured with a margin,
@ -328,7 +328,7 @@ adjust the [Remote Configuration](#remote-configuration) of this depending on yo
This is how the curve looks like for `acceptable-heartbeat-pause` configured to This is how the curve looks like for `acceptable-heartbeat-pause` configured to
3 seconds. 3 seconds.
![phi3.png](../images/phi3.png) ![phi3.png](./images/phi3.png)
## Serialization ## Serialization

View file

@ -11,7 +11,7 @@ be processed arrive and leave the stage. In this view, a `Source` is nothing els
output port, or, a `BidiFlow` is a "box" with exactly two input and two output ports. In the figure below output port, or, a `BidiFlow` is a "box" with exactly two input and two output ports. In the figure below
we illustrate the most common used stages viewed as "boxes". we illustrate the most common used stages viewed as "boxes".
![compose_shapes.png](../../images/compose_shapes.png) ![compose_shapes.png](../images/compose_shapes.png)
The *linear* stages are `Source`, `Sink` The *linear* stages are `Source`, `Sink`
and `Flow`, as these can be used to compose strict chains of processing stages. and `Flow`, as these can be used to compose strict chains of processing stages.
@ -31,7 +31,7 @@ to interact with. One good example is the `Http` server component, which is enco
The following figure demonstrates various composite stages, that contain various other type of stages internally, but The following figure demonstrates various composite stages, that contain various other type of stages internally, but
hiding them behind a *shape* that looks like a `Source`, `Flow`, etc. hiding them behind a *shape* that looks like a `Source`, `Flow`, etc.
![compose_composites.png](../../images/compose_composites.png) ![compose_composites.png](../images/compose_composites.png)
One interesting example above is a `Flow` which is composed of a disconnected `Sink` and `Source`. One interesting example above is a `Flow` which is composed of a disconnected `Sink` and `Source`.
This can be achieved by using the `fromSinkAndSource()` constructor method on `Flow` which takes the two parts as This can be achieved by using the `fromSinkAndSource()` constructor method on `Flow` which takes the two parts as
@ -54,7 +54,7 @@ These mechanics allow arbitrary nesting of modules. For example the following fi
that is built from a composite `Source` and a composite `Sink` (which in turn contains a composite that is built from a composite `Source` and a composite `Sink` (which in turn contains a composite
`Flow`). `Flow`).
![compose_nested_flow.png](../../images/compose_nested_flow.png) ![compose_nested_flow.png](../images/compose_nested_flow.png)
The above diagram contains one more shape that we have not seen yet, which is called `RunnableGraph`. It turns The above diagram contains one more shape that we have not seen yet, which is called `RunnableGraph`. It turns
out, that if we wire all exposed ports together, so that no more open ports remain, we get a module that is *closed*. out, that if we wire all exposed ports together, so that no more open ports remain, we get a module that is *closed*.
@ -90,7 +90,7 @@ Once we have hidden the internals of our components, they act like any other bui
we hide some of the internals of our composites, the result looks just like if any other predefine component has been we hide some of the internals of our composites, the result looks just like if any other predefine component has been
used: used:
![compose_nested_flow_opaque.png](../../images/compose_nested_flow_opaque.png) ![compose_nested_flow_opaque.png](../images/compose_nested_flow_opaque.png)
If we look at usage of built-in components, and our custom components, there is no difference in usage as the code If we look at usage of built-in components, and our custom components, there is no difference in usage as the code
snippet below demonstrates. snippet below demonstrates.
@ -112,7 +112,7 @@ operate on are uniform across all DSLs and fit together nicely.
As a first example, let's look at a more complex layout: As a first example, let's look at a more complex layout:
![compose_graph.png](../../images/compose_graph.png) ![compose_graph.png](../images/compose_graph.png)
The diagram shows a `RunnableGraph` (remember, if there are no unwired ports, the graph is closed, and therefore The diagram shows a `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,
@ -140,7 +140,7 @@ the layout is flat, not modularized. We will modify our example, and create a re
The way to do it is to use the `create()` factory method on `GraphDSL`. If we remove the sources and sinks The way to do it is to use the `create()` factory method on `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:
![compose_graph_partial.png](../../images/compose_graph_partial.png) ![compose_graph_partial.png](../images/compose_graph_partial.png)
We can recreate a similar graph in code, using the DSL in a similar way than before: We can recreate a similar graph in code, using the DSL in a similar way than before:
@ -159,7 +159,7 @@ matching built-in ones.
The resulting graph is already a properly wrapped module, so there is no need to call *named()* to encapsulate the graph, but The resulting graph is already a properly wrapped module, so there is no need to call *named()* to encapsulate the graph, but
it is a good practice to give names to modules to help debugging. it is a good practice to give names to modules to help debugging.
![compose_graph_shape.png](../../images/compose_graph_shape.png) ![compose_graph_shape.png](../images/compose_graph_shape.png)
Since our partial graph has the right shape, it can be already used in the simpler, linear DSL: Since our partial graph has the right shape, it can be already used in the simpler, linear DSL:
@ -175,7 +175,7 @@ has a `fromGraph()` method that just adds the DSL to a `FlowShape`. There are si
For convenience, it is also possible to skip the partial graph creation, and use one of the convenience creator methods. For convenience, it is also possible to skip the partial graph creation, and use one of the convenience creator methods.
To demonstrate this, we will create the following graph: To demonstrate this, we will create the following graph:
![compose_graph_flow.png](../../images/compose_graph_flow.png) ![compose_graph_flow.png](../images/compose_graph_flow.png)
The code version of the above closed graph might look like this: The code version of the above closed graph might look like this:
@ -239,7 +239,7 @@ We demonstrate how this works by a code example and a diagram which graphically
The propagation of the individual materialized values from the enclosed modules towards the top will look like this: The propagation of the individual materialized values from the enclosed modules towards the top will look like this:
![compose_mat.png](../../images/compose_mat.png) ![compose_mat.png](../images/compose_mat.png)
To implement the above, first, we create a composite `Source`, where the enclosed `Source` have a To implement the above, first, we create a composite `Source`, where the enclosed `Source` have a
materialized type of @scala[`Promise[[Option[Int]]`] @java[`CompletableFuture<Optional<Integer>>>`]. By using the combiner function `Keep.left`, the resulting materialized materialized type of @scala[`Promise[[Option[Int]]`] @java[`CompletableFuture<Optional<Integer>>>`]. By using the combiner function `Keep.left`, the resulting materialized
@ -317,7 +317,7 @@ the same attribute explicitly set. `nestedSource` gets the default attributes fr
on the other hand has this attribute set, so it will be used by all nested modules. `nestedFlow` will inherit from `nestedSink` on the other hand has this attribute set, so it will be used by all nested modules. `nestedFlow` will inherit from `nestedSink`
except the `map` stage which has again an explicitly provided attribute overriding the inherited one. except the `map` stage which has again an explicitly provided attribute overriding the inherited one.
![compose_attributes.png](../../images/compose_attributes.png) ![compose_attributes.png](../images/compose_attributes.png)
This diagram illustrates the inheritance process for the example code (representing the materializer default attributes This diagram illustrates the inheritance process for the example code (representing the materializer default attributes
as the color *red*, the attributes set on `nestedSink` as *blue* and the attributes set on `nestedFlow` as *green*). as the color *red*, the attributes set on `nestedSink` as *blue* and the attributes set on `nestedFlow` as *green*).

View file

@ -109,7 +109,7 @@ the initial state while orange indicates the end state. If an operation is not l
to call it while the port is in that state. If an event is not listed for a state, then that event cannot happen to call it while the port is in that state. If an event is not listed for a state, then that event cannot happen
in that state. in that state.
![outport_transitions.png](../../images/outport_transitions.png) ![outport_transitions.png](../images/outport_transitions.png)
The following operations are available for *input* ports: The following operations are available for *input* ports:
@ -140,7 +140,7 @@ the initial state while orange indicates the end state. If an operation is not l
to call it while the port is in that state. If an event is not listed for a state, then that event cannot happen to call it while the port is in that state. If an event is not listed for a state, then that event cannot happen
in that state. in that state.
![inport_transitions.png](../../images/inport_transitions.png) ![inport_transitions.png](../images/inport_transitions.png)
Finally, there are two methods available for convenience to complete the stage and all of its ports: Finally, there are two methods available for convenience to complete the stage and all of its ports:
@ -178,11 +178,11 @@ Such a stage can be illustrated as a box with two flows as it is
seen in the illustration below. Demand flowing upstream leading to elements seen in the illustration below. Demand flowing upstream leading to elements
flowing downstream. flowing downstream.
![graph_stage_conceptual.png](../../images/graph_stage_conceptual.png) ![graph_stage_conceptual.png](../images/graph_stage_conceptual.png)
To illustrate these concepts we create a small `GraphStage` that implements the `map` transformation. To illustrate these concepts we create a small `GraphStage` that implements the `map` transformation.
![graph_stage_map.png](../../images/graph_stage_map.png) ![graph_stage_map.png](../images/graph_stage_map.png)
Map calls `push(out)` from the `onPush()` handler and it also calls `pull()` from the `onPull` handler resulting in the Map calls `push(out)` from the `onPush()` handler and it also calls `pull()` from the `onPull` handler resulting in the
conceptual wiring above, and fully expressed in code below: conceptual wiring above, and fully expressed in code below:
@ -199,7 +199,7 @@ demand is passed along upstream elements passed on downstream.
To demonstrate a many-to-one stage we will implement To demonstrate a many-to-one stage we will implement
filter. The conceptual wiring of `Filter` looks like this: filter. The conceptual wiring of `Filter` looks like this:
![graph_stage_filter.png](../../images/graph_stage_filter.png) ![graph_stage_filter.png](../images/graph_stage_filter.png)
As we see above, if the given predicate matches the current element we are propagating it downwards, otherwise As we see above, if the given predicate matches the current element we are propagating it downwards, otherwise
we return the “ball” to our upstream so that we get the new element. This is achieved by modifying the map we return the “ball” to our upstream so that we get the new element. This is achieved by modifying the map
@ -215,7 +215,7 @@ Java
To complete the picture we define a one-to-many transformation as the next step. We chose a straightforward example stage To complete the picture we define a one-to-many transformation as the next step. We chose a straightforward example stage
that emits every upstream element twice downstream. The conceptual wiring of this stage looks like this: that emits every upstream element twice downstream. The conceptual wiring of this stage looks like this:
![graph_stage_duplicate.png](../../images/graph_stage_duplicate.png) ![graph_stage_duplicate.png](../images/graph_stage_duplicate.png)
This is a stage that has state: an option with the last element it has seen indicating if it This is a stage that has state: an option with the last element it has seen indicating if it
has duplicated this last element already or not. We must also make sure to emit the extra element has duplicated this last element already or not. We must also make sure to emit the extra element
@ -247,7 +247,7 @@ Java
Finally, to demonstrate all of the stages above, we put them together into a processing chain, Finally, to demonstrate all of the stages above, we put them together into a processing chain,
which conceptually would correspond to the following structure: which conceptually would correspond to the following structure:
![graph_stage_chain.png](../../images/graph_stage_chain.png) ![graph_stage_chain.png](../images/graph_stage_chain.png)
In code this is only a few lines, using the `via` use our custom stages in a stream: In code this is only a few lines, using the `via` use our custom stages in a stream:
@ -260,7 +260,7 @@ Java
If we attempt to draw the sequence of events, it shows that there is one "event token" If we attempt to draw the sequence of events, it shows that there is one "event token"
in circulation in a potential chain of stages, just like our conceptual "railroad tracks" representation predicts. in circulation in a potential chain of stages, just like our conceptual "railroad tracks" representation predicts.
![graph_stage_tracks_1.png](../../images/graph_stage_tracks_1.png) ![graph_stage_tracks_1.png](../images/graph_stage_tracks_1.png)
### Completion ### Completion
@ -432,12 +432,12 @@ The next diagram illustrates the event sequence for a buffer with capacity of tw
the downstream demand is slow to start and the buffer will fill up with upstream elements before any demand the downstream demand is slow to start and the buffer will fill up with upstream elements before any demand
is seen from downstream. is seen from downstream.
![graph_stage_detached_tracks_1.png](../../images/graph_stage_detached_tracks_1.png) ![graph_stage_detached_tracks_1.png](../images/graph_stage_detached_tracks_1.png)
Another scenario would be where the demand from downstream starts coming in before any element is pushed Another scenario would be where the demand from downstream starts coming in before any element is pushed
into the buffer stage. into the buffer stage.
![graph_stage_detached_tracks_2.png](../../images/graph_stage_detached_tracks_2.png) ![graph_stage_detached_tracks_2.png](../images/graph_stage_detached_tracks_2.png)
The first difference we can notice is that our `Buffer` stage is automatically pulling its upstream on The first difference we can notice is that our `Buffer` stage is automatically pulling its upstream on
initialization. The buffer has demand for up to two elements without any downstream demand. initialization. The buffer has demand for up to two elements without any downstream demand.

View file

@ -296,7 +296,7 @@ work on the tasks in parallel. It is important to note that asynchronous boundar
flow where elements are passed asynchronously (as in other streaming libraries), but instead attributes always work flow where elements are passed asynchronously (as in other streaming libraries), but instead attributes always work
by adding information to the flow graph that has been constructed up to this point: by adding information to the flow graph that has been constructed up to this point:
![asyncBoundary.png](../../images/asyncBoundary.png) ![asyncBoundary.png](../images/asyncBoundary.png)
This means that everything that is inside the red bubble will be executed by one actor and everything outside of it This means that everything that is inside the red bubble will be executed by one actor and everything outside of it
by another. This scheme can be applied successively, always having one such boundary enclose the previous ones plus all by another. This scheme can be applied successively, always having one such boundary enclose the previous ones plus all

View file

@ -40,7 +40,7 @@ One of the goals of the GraphDSL DSL is to look similar to how one would draw a
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:
![simple-graph-example.png](../../images/simple-graph-example.png) ![simple-graph-example.png](../images/simple-graph-example.png)
Such graph is simple to translate to the Graph DSL since each linear element corresponds to a `Flow`, Such graph is simple to translate to the Graph DSL since each linear element corresponds to a `Flow`,
and each circle corresponds to either a `Junction` or a `Source` or `Sink` if it is beginning and each circle corresponds to either a `Junction` or a `Source` or `Sink` if it is beginning

View file

@ -18,7 +18,7 @@ Scala
Java Java
: @@snip [StreamTcpDocTest.java]($code$/java/jdocs/stream/io/StreamTcpDocTest.java) { #echo-server-simple-bind } : @@snip [StreamTcpDocTest.java]($code$/java/jdocs/stream/io/StreamTcpDocTest.java) { #echo-server-simple-bind }
![tcp-stream-bind.png](../../images/tcp-stream-bind.png) ![tcp-stream-bind.png](../images/tcp-stream-bind.png)
Next, we simply handle *each* incoming connection using a `Flow` which will be used as the processing stage Next, we simply handle *each* incoming connection using a `Flow` which will be used as the processing stage
to handle and emit `ByteString` s from and to the TCP Socket. Since one `ByteString` does not have to necessarily to handle and emit `ByteString` s from and to the TCP Socket. Since one `ByteString` does not have to necessarily
@ -33,7 +33,7 @@ Scala
Java Java
: @@snip [StreamTcpDocTest.java]($code$/java/jdocs/stream/io/StreamTcpDocTest.java) { #echo-server-simple-handle } : @@snip [StreamTcpDocTest.java]($code$/java/jdocs/stream/io/StreamTcpDocTest.java) { #echo-server-simple-handle }
![tcp-stream-run.png](../../images/tcp-stream-run.png) ![tcp-stream-run.png](../images/tcp-stream-run.png)
Notice that while most building blocks in Akka Streams are reusable and freely shareable, this is *not* the case for the Notice that while most building blocks in Akka Streams are reusable and freely shareable, this is *not* the case for the
incoming connection Flow, since it directly corresponds to an existing, already accepted connection its handling can incoming connection Flow, since it directly corresponds to an existing, already accepted connection its handling can