Use apidoc directive in routing.md (#22904) (#31339)

This commit is contained in:
Andrei Arlou 2022-04-14 12:08:45 +03:00 committed by GitHub
parent f6d880fed9
commit 934b5a055a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -19,7 +19,7 @@ To use Routing, you must add the following dependency in your project:
## Introduction ## Introduction
Messages can be sent via a router to efficiently route them to destination actors, known as Messages can be sent via a router to efficiently route them to destination actors, known as
its *routees*. A `Router` can be used inside or outside of an actor, and you can manage the its *routees*. A @apidoc[akka.routing.Router] can be used inside or outside of an actor, and you can manage the
routees yourselves or use a self contained router actor with configuration capabilities. routees yourselves or use a self contained router actor with configuration capabilities.
Different routing strategies can be used, according to your application's needs. Akka comes with Different routing strategies can be used, according to your application's needs. Akka comes with
@ -37,26 +37,26 @@ Scala
Java Java
: @@snip [RouterDocTest.java](/akka-docs/src/test/java/jdocs/routing/RouterDocTest.java) { #router-in-actor } : @@snip [RouterDocTest.java](/akka-docs/src/test/java/jdocs/routing/RouterDocTest.java) { #router-in-actor }
We create a `Router` and specify that it should use `RoundRobinRoutingLogic` when routing the We create a `Router` and specify that it should use @apidoc[akka.routing.RoundRobinRoutingLogic] when routing the
messages to the routees. messages to the routees.
The routing logic shipped with Akka are: The routing logic shipped with Akka are:
* `akka.routing.RoundRobinRoutingLogic` * @apidoc[akka.routing.RoundRobinRoutingLogic]
* `akka.routing.RandomRoutingLogic` * @apidoc[akka.routing.RandomRoutingLogic]
* `akka.routing.SmallestMailboxRoutingLogic` * @apidoc[akka.routing.SmallestMailboxRoutingLogic]
* `akka.routing.BroadcastRoutingLogic` * @apidoc[akka.routing.BroadcastRoutingLogic]
* `akka.routing.ScatterGatherFirstCompletedRoutingLogic` * @apidoc[akka.routing.ScatterGatherFirstCompletedRoutingLogic]
* `akka.routing.TailChoppingRoutingLogic` * @apidoc[akka.routing.TailChoppingRoutingLogic]
* `akka.routing.ConsistentHashingRoutingLogic` * @apidoc[akka.routing.ConsistentHashingRoutingLogic]
We create the routees as ordinary child actors wrapped in `ActorRefRoutee`. We watch We create the routees as ordinary child actors wrapped in @apidoc[akka.routing.ActorRefRoutee]. We watch
the routees to be able to replace them if they are terminated. the routees to be able to replace them if they are terminated.
Sending messages via the router is done with the `route` method, as is done for the `Work` messages Sending messages via the router is done with the @apidoc[route](akka.routing.Router) {scala="#route(message:Any,sender:akka.actor.ActorRef):Unit" java="#route(java.lang.Object,akka.actor.ActorRef)"} method, as is done for the `Work` messages
in the example above. in the example above.
The `Router` is immutable and the `RoutingLogic` is thread safe; meaning that they can also be used The `Router` is immutable and the @apidoc[akka.routing.RoutingLogic] is thread safe; meaning that they can also be used
outside of actors. outside of actors.
@@@ note @@@ note
@ -87,7 +87,7 @@ This is in contrast with Remote Deployment where such marker props is not necess
If the props of an actor is NOT wrapped in `FromConfig` it will ignore the router section of the deployment configuration. If the props of an actor is NOT wrapped in `FromConfig` it will ignore the router section of the deployment configuration.
You send messages to the routees via the router actor in the same way as for ordinary actors, You send messages to the routees via the router actor in the same way as for ordinary actors,
i.e. via its `ActorRef`. The router actor forwards messages onto its routees without changing i.e. via its @apidoc[akka.actor.ActorRef]. The router actor forwards messages onto its routees without changing
the original sender. When a routee replies to a routed message, the reply will be sent to the the original sender. When a routee replies to a routed message, the reply will be sent to the
original sender, not to the router actor. original sender, not to the router actor.
@ -125,7 +125,7 @@ Java
In addition to being able to create local actors as routees, you can instruct the router to In addition to being able to create local actors as routees, you can instruct the router to
deploy its created children on a set of remote hosts. Routees will be deployed in round-robin deploy its created children on a set of remote hosts. Routees will be deployed in round-robin
fashion. In order to deploy routees remotely, wrap the router configuration in a fashion. In order to deploy routees remotely, wrap the router configuration in a
`RemoteRouterConfig`, attaching the remote addresses of the nodes to deploy to. Remote @apidoc[akka.remote.routing.RemoteRouterConfig], attaching the remote addresses of the nodes to deploy to. Remote
deployment requires the `akka-remote` module to be included in the classpath. deployment requires the `akka-remote` module to be included in the classpath.
Scala Scala
@ -175,7 +175,7 @@ while still re-creating the children, will still preserve the same number of act
This means that if you have not specified `supervisorStrategy` of the router or its parent a This means that if you have not specified `supervisorStrategy` of the router or its parent a
failure in a routee will escalate to the parent of the router, which will by default restart the router, failure in a routee will escalate to the parent of the router, which will by default restart the router,
which will restart all routees (it uses Escalate and does not stop routees during restart). The reason which will restart all routees (it uses Escalate and does not stop routees during restart). The reason
is to make the default behave such that adding `.withRouter` to a childs definition does not is to make the default behave such that adding @apidoc[withRouter](akka.actor.Props) {scala="#withRouter(r:akka.routing.RouterConfig):akka.actor.Props" java="#withRouter(akka.routing.RouterConfig)"} to a childs definition does not
change the supervision strategy applied to the child. This might be an inefficiency that you can avoid change the supervision strategy applied to the child. This might be an inefficiency that you can avoid
by specifying the strategy when defining the router. by specifying the strategy when defining the router.
@ -200,7 +200,7 @@ a resizer.
Sometimes, rather than having the router actor create its routees, it is desirable to create routees Sometimes, rather than having the router actor create its routees, it is desirable to create routees
separately and provide them to the router for its use. You can do this by passing in separately and provide them to the router for its use. You can do this by passing in
paths of the routees to the router's configuration. Messages will be sent with `ActorSelection` paths of the routees to the router's configuration. Messages will be sent with @apidoc[akka.actor.ActorSelection]
to these paths, wildcards can be and will result in the same semantics as explicitly using `ActorSelection`. to these paths, wildcards can be and will result in the same semantics as explicitly using `ActorSelection`.
The example below shows how to create a router by providing it with the path strings of three The example below shows how to create a router by providing it with the path strings of three
@ -390,7 +390,7 @@ configuration.
@@snip [RouterDocSpec.scala](/akka-docs/src/test/scala/docs/routing/RouterDocSpec.scala) { #config-balancing-pool2 } @@snip [RouterDocSpec.scala](/akka-docs/src/test/scala/docs/routing/RouterDocSpec.scala) { #config-balancing-pool2 }
The `BalancingPool` automatically uses a special `BalancingDispatcher` for its The @apidoc[BalancingPool] automatically uses a special `BalancingDispatcher` for its
routees - disregarding any dispatcher that is set on the routee Props object. routees - disregarding any dispatcher that is set on the routee Props object.
This is needed in order to implement the balancing semantics via This is needed in order to implement the balancing semantics via
sharing the same mailbox by all the routees. sharing the same mailbox by all the routees.
@ -511,7 +511,7 @@ It then waits for first reply it gets back. This result will be sent back to ori
Other replies are discarded. Other replies are discarded.
It is expecting at least one reply within a configured duration, otherwise it will reply with It is expecting at least one reply within a configured duration, otherwise it will reply with
`akka.pattern.AskTimeoutException` in a `akka.actor.Status.Failure`. @apidoc[akka.pattern.AskTimeoutException] in a @apidoc[akka.actor.Status.Failure].
ScatterGatherFirstCompletedPool defined in configuration: ScatterGatherFirstCompletedPool defined in configuration:
@ -608,13 +608,13 @@ insight into how consistent hashing is implemented.
There is 3 ways to define what data to use for the consistent hash key. There is 3 ways to define what data to use for the consistent hash key.
* You can define @scala[`hashMapping`]@java[`withHashMapper`] of the router to map incoming * You can define @scala[`hashMapping`]@java[@javadoc[withHashMapper](akka.routing.ConsistentHashingRoutingLogic#withHashMapper(akka.routing.ConsistentHashingRouter.ConsistentHashMapper))] of the router to map incoming
messages to their consistent hash key. This makes the decision messages to their consistent hash key. This makes the decision
transparent for the sender. transparent for the sender.
* The messages may implement `akka.routing.ConsistentHashingRouter.ConsistentHashable`. * The messages may implement @apidoc[akka.routing.ConsistentHashingRouter.ConsistentHashable].
The key is part of the message and it's convenient to define it together The key is part of the message and it's convenient to define it together
with the message definition. with the message definition.
* The messages can be wrapped in a `akka.routing.ConsistentHashingRouter.ConsistentHashableEnvelope` * The messages can be wrapped in a @apidoc[akka.routing.ConsistentHashingRouter.ConsistentHashableEnvelope]
to define what data to use for the consistent hash key. The sender knows to define what data to use for the consistent hash key. The sender knows
the key to use. the key to use.
@ -685,8 +685,8 @@ consistent hash node ring to make the distribution more uniform.
Most messages sent to router actors will be forwarded according to the routers' routing logic. Most messages sent to router actors will be forwarded according to the routers' routing logic.
However there are a few types of messages that have special behavior. However there are a few types of messages that have special behavior.
Note that these special messages, except for the `Broadcast` message, are only handled by Note that these special messages, except for the @apidoc[akka.routing.Broadcast] message, are only handled by
self contained router actors and not by the `akka.routing.Router` component described self contained router actors and not by the @apidoc[akka.routing.Router] component described
in @ref:[A Simple Router](#simple-router). in @ref:[A Simple Router](#simple-router).
### Broadcast Messages ### Broadcast Messages
@ -718,7 +718,7 @@ possibly get the broadcast message multiple times, while other routees get no br
### PoisonPill Messages ### PoisonPill Messages
A `PoisonPill` message has special handling for all actors, including for routers. When any actor A @apidoc[akka.actor.PoisonPill] message has special handling for all actors, including for routers. When any actor
receives a `PoisonPill` message, that actor will be stopped. See the @ref:[PoisonPill](actors.md#poison-pill) receives a `PoisonPill` message, that actor will be stopped. See the @ref:[PoisonPill](actors.md#poison-pill)
documentation for details. documentation for details.
@ -757,11 +757,11 @@ automatically unless it is a dynamic router, e.g. using a resizer.
### Kill Messages ### Kill Messages
`Kill` messages are another type of message that has special handling. See @apidoc[akka.actor.Kill] messages are another type of message that has special handling. See
@ref:[Killing an Actor](actors.md#killing-actors) for general information about how actors handle `Kill` messages. @ref:[Killing an Actor](actors.md#killing-actors) for general information about how actors handle `Kill` messages.
When a `Kill` message is sent to a router the router processes the message internally, and does When a `Kill` message is sent to a router the router processes the message internally, and does
*not* send it on to its routees. The router will throw an `ActorKilledException` and fail. It *not* send it on to its routees. The router will throw an @apidoc[ActorKilledException] and fail. It
will then be either resumed, restarted or terminated, depending how it is supervised. will then be either resumed, restarted or terminated, depending how it is supervised.
Routees that are children of the router will also be suspended, and will be affected by the Routees that are children of the router will also be suspended, and will be affected by the
@ -774,10 +774,10 @@ Scala
Java Java
: @@snip [RouterDocTest.java](/akka-docs/src/test/java/jdocs/routing/RouterDocTest.java) { #kill } : @@snip [RouterDocTest.java](/akka-docs/src/test/java/jdocs/routing/RouterDocTest.java) { #kill }
As with the `PoisonPill` message, there is a distinction between killing a router, which As with the @apidoc[akka.actor.PoisonPill] message, there is a distinction between killing a router, which
indirectly kills its children (who happen to be routees), and killing routees directly (some of whom indirectly kills its children (who happen to be routees), and killing routees directly (some of whom
may not be children.) To kill routees directly the router should be sent a `Kill` message wrapped may not be children.) To kill routees directly the router should be sent a `Kill` message wrapped
in a `Broadcast` message. in a @apidoc[akka.routing.Broadcast] message.
Scala Scala
: @@snip [RouterDocSpec.scala](/akka-docs/src/test/scala/docs/routing/RouterDocSpec.scala) { #broadcastKill } : @@snip [RouterDocSpec.scala](/akka-docs/src/test/scala/docs/routing/RouterDocSpec.scala) { #broadcastKill }
@ -787,11 +787,11 @@ Java
### Management Messages ### Management Messages
* Sending `akka.routing.GetRoutees` to a router actor will make it send back its currently used routees * Sending @apidoc[akka.routing.GetRoutees] to a router actor will make it send back its currently used routees
in a `akka.routing.Routees` message. in a @apidoc[akka.routing.Routees] message.
* Sending `akka.routing.AddRoutee` to a router actor will add that routee to its collection of routees. * Sending @apidoc[akka.routing.AddRoutee] to a router actor will add that routee to its collection of routees.
* Sending `akka.routing.RemoveRoutee` to a router actor will remove that routee to its collection of routees. * Sending @apidoc[akka.routing.RemoveRoutee] to a router actor will remove that routee to its collection of routees.
* Sending `akka.routing.AdjustPoolSize` to a pool router actor will add or remove that number of routees to * Sending @apidoc[akka.routing.AdjustPoolSize] to a pool router actor will add or remove that number of routees to
its collection of routees. its collection of routees.
These management messages may be handled after other messages, so if you send `AddRoutee` immediately followed by These management messages may be handled after other messages, so if you send `AddRoutee` immediately followed by
@ -805,7 +805,7 @@ and when you receive the `Routees` reply you know that the preceding change has
@scala[Most]@java[All] pools can be used with a fixed number of routees or with a resize strategy to adjust the number @scala[Most]@java[All] pools can be used with a fixed number of routees or with a resize strategy to adjust the number
of routees dynamically. of routees dynamically.
There are two types of resizers: the default `Resizer` and the `OptimalSizeExploringResizer`. There are two types of resizers: the default @apidoc[akka.routing.Resizer] and the @apidoc[akka.routing.OptimalSizeExploringResizer].
### Default Resizer ### Default Resizer
@ -839,7 +839,7 @@ will be used instead of any programmatically sent parameters.*
### Optimal Size Exploring Resizer ### Optimal Size Exploring Resizer
The `OptimalSizeExploringResizer` resizes the pool to an optimal size that provides the most message throughput. The @apidoc[akka.routing.OptimalSizeExploringResizer] resizes the pool to an optimal size that provides the most message throughput.
This resizer works best when you expect the pool size to performance function to be a convex function. This resizer works best when you expect the pool size to performance function to be a convex function.
For example, when you have a CPU bound tasks, the optimal size is bound to the number of CPU cores. For example, when you have a CPU bound tasks, the optimal size is bound to the number of CPU cores.
@ -898,7 +898,7 @@ routees.
A normal actor can be used for routing messages, but an actor's single-threaded processing can A normal actor can be used for routing messages, but an actor's single-threaded processing can
become a bottleneck. Routers can achieve much higher throughput with an optimization to the usual become a bottleneck. Routers can achieve much higher throughput with an optimization to the usual
message-processing pipeline that allows concurrent routing. This is achieved by embedding routers' message-processing pipeline that allows concurrent routing. This is achieved by embedding routers'
routing logic directly in their `ActorRef` rather than in the router actor. Messages sent to routing logic directly in their @apidoc[akka.actor.ActorRef] rather than in the router actor. Messages sent to
a router's `ActorRef` can be immediately routed to the routee, bypassing the single-threaded a router's `ActorRef` can be immediately routed to the routee, bypassing the single-threaded
router actor entirely. router actor entirely.
@ -931,7 +931,7 @@ Java
: @@snip [CustomRouterDocTest.java](/akka-docs/src/test/java/jdocs/routing/CustomRouterDocTest.java) { #routing-logic } : @@snip [CustomRouterDocTest.java](/akka-docs/src/test/java/jdocs/routing/CustomRouterDocTest.java) { #routing-logic }
`select` will be called for each message and in this example pick a few destinations by round-robin, `select` will be called for each message and in this example pick a few destinations by round-robin,
by reusing the existing `RoundRobinRoutingLogic` and wrap the result in a `SeveralRoutees` by reusing the existing @apidoc[akka.routing.RoundRobinRoutingLogic] and wrap the result in a @apidoc[akka.routing.SeveralRoutees]
instance. `SeveralRoutees` will send the message to all of the supplied routes. instance. `SeveralRoutees` will send the message to all of the supplied routes.
The implementation of the routing logic must be thread safe, since it might be used outside of actors. The implementation of the routing logic must be thread safe, since it might be used outside of actors.
@ -949,7 +949,7 @@ as described in @ref:[A Simple Router](#simple-router).
Let us continue and make this into a self contained, configurable, router actor. Let us continue and make this into a self contained, configurable, router actor.
Create a class that extends `Pool`, `Group` or `CustomRouterConfig`. That class is a factory Create a class that extends @apidoc[akka.routing.Pool], @apidoc[akka.routing.Group] or @apidoc[akka.routing.CustomRouterConfig]. That class is a factory
for the routing logic and holds the configuration for the router. Here we make it a `Group`. for the routing logic and holds the configuration for the router. Here we make it a `Group`.
Scala Scala
@ -966,7 +966,7 @@ Scala
Java Java
: @@snip [CustomRouterDocTest.java](/akka-docs/src/test/java/jdocs/routing/CustomRouterDocTest.java) { #usage-1 } : @@snip [CustomRouterDocTest.java](/akka-docs/src/test/java/jdocs/routing/CustomRouterDocTest.java) { #usage-1 }
Note that we added a constructor in `RedundancyGroup` that takes a `Config` parameter. Note that we added a constructor in `RedundancyGroup` that takes a @javadoc[Config](com.typesafe.config.Config) parameter.
That makes it possible to define it in configuration. That makes it possible to define it in configuration.
Scala Scala
@ -989,7 +989,7 @@ Java
## Configuring Dispatchers ## Configuring Dispatchers
The dispatcher for created children of the pool will be taken from The dispatcher for created children of the pool will be taken from
`Props` as described in @ref:[Dispatchers](dispatchers.md). @apidoc[akka.actor.Props] as described in @ref:[Dispatchers](dispatchers.md).
To make it easy to define the dispatcher of the routees of the pool you can To make it easy to define the dispatcher of the routees of the pool you can
define the dispatcher inline in the deployment section of the config. define the dispatcher inline in the deployment section of the config.
@ -1009,8 +1009,8 @@ after it has been created.
The “head” router cannot always run on the same dispatcher, because it The “head” router cannot always run on the same dispatcher, because it
does not process the same type of messages, hence this special actor does does not process the same type of messages, hence this special actor does
not use the dispatcher configured in `Props`, but takes the not use the dispatcher configured in @apidoc[akka.actor.Props], but takes the
`routerDispatcher` from the `RouterConfig` instead, which defaults to `routerDispatcher` from the @apidoc[akka.routing.RouterConfig] instead, which defaults to
the actor systems default dispatcher. All standard routers allow setting this the actor systems default dispatcher. All standard routers allow setting this
property in their constructor or factory method, custom routers have to property in their constructor or factory method, custom routers have to
implement the method in a suitable way. implement the method in a suitable way.
@ -1024,7 +1024,7 @@ Java
@@@ note @@@ note
It is not allowed to configure the `routerDispatcher` to be a It is not allowed to configure the `routerDispatcher` to be a
`akka.dispatch.BalancingDispatcherConfigurator` since the messages meant @apidoc[akka.dispatch.BalancingDispatcherConfigurator] since the messages meant
for the special router actor cannot be processed by any other actor. for the special router actor cannot be processed by any other actor.
@@@ @@@