Move generic mailbox docs from classic to main mailboxes doc (#27493)
* Move generic mailbox docs from classic to main mailboxes doc * 'Mailbox configuration examples' could still be converted, but let's keep PR's small * Clarify configuration mailbox selection Co-Authored-By: Helena Edelson <helena@users.noreply.github.com>
This commit is contained in:
parent
29b95f166a
commit
fcd6185265
2 changed files with 182 additions and 189 deletions
|
|
@ -27,6 +27,8 @@ An Akka `Mailbox` holds the messages that are destined for an `Actor`.
|
|||
Normally each `Actor` has its own mailbox, but with for example a `BalancingPool`
|
||||
all routees will share a single mailbox instance.
|
||||
|
||||
For more details on advanced mailbox config and custom mailbox implementations, see @ref[Mailboxes](typed/mailboxes.md#mailbox-implementations).
|
||||
|
||||
## Mailbox Selection
|
||||
|
||||
### Requiring a Message Queue Type for an Actor
|
||||
|
|
@ -60,148 +62,7 @@ The type of the queue in the mailbox created for an actor will be checked agains
|
|||
### Requiring a Message Queue Type for a Dispatcher
|
||||
|
||||
A dispatcher may also have a requirement for the mailbox type used by the
|
||||
actors running on it. An example is the BalancingDispatcher which requires a
|
||||
message queue that is thread-safe for multiple concurrent consumers. Such a
|
||||
requirement is formulated within the dispatcher configuration section like
|
||||
this:
|
||||
|
||||
```
|
||||
my-dispatcher {
|
||||
mailbox-requirement = org.example.MyInterface
|
||||
}
|
||||
```
|
||||
|
||||
The given requirement names a class or interface which will then be ensured to
|
||||
be a supertype of the message queue’s implementation. In case of a
|
||||
conflict—e.g. if the actor requires a mailbox type which does not satisfy this
|
||||
requirement—then actor creation will fail.
|
||||
|
||||
### How the Mailbox Type is Selected
|
||||
|
||||
When an actor is created, the `ActorRefProvider` first determines the
|
||||
dispatcher which will execute it. Then the mailbox is determined as follows:
|
||||
|
||||
1. If the actor’s deployment configuration section contains a `mailbox` key
|
||||
then that names a configuration section describing the mailbox type to be
|
||||
used.
|
||||
2. If the actor’s `Props` contains a mailbox selection—i.e. `withMailbox`
|
||||
was called on it—then that names a configuration section describing the
|
||||
mailbox type to be used (note that this needs to be an absolute config path,
|
||||
for example `myapp.special-mailbox`, and is not nested inside the `akka` namespace).
|
||||
3. If the dispatcher’s configuration section contains a `mailbox-type` key
|
||||
the same section will be used to configure the mailbox type.
|
||||
4. If the actor requires a mailbox type as described above then the mapping for
|
||||
that requirement will be used to determine the mailbox type to be used; if
|
||||
that fails then the dispatcher’s requirement—if any—will be tried instead.
|
||||
5. If the dispatcher requires a mailbox type as described above then the
|
||||
mapping for that requirement will be used to determine the mailbox type to
|
||||
be used.
|
||||
6. The default mailbox `akka.actor.default-mailbox` will be used.
|
||||
|
||||
### Default Mailbox
|
||||
|
||||
When the mailbox is not specified as described above the default mailbox
|
||||
is used. By default it is an unbounded mailbox, which is backed by a
|
||||
`java.util.concurrent.ConcurrentLinkedQueue`.
|
||||
|
||||
`SingleConsumerOnlyUnboundedMailbox` is an even more efficient mailbox, and
|
||||
it can be used as the default mailbox, but it cannot be used with a BalancingDispatcher.
|
||||
|
||||
Configuration of `SingleConsumerOnlyUnboundedMailbox` as default mailbox:
|
||||
|
||||
```
|
||||
akka.actor.default-mailbox {
|
||||
mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox"
|
||||
}
|
||||
```
|
||||
|
||||
### Which Configuration is passed to the Mailbox Type
|
||||
|
||||
Each mailbox type is implemented by a class which extends `MailboxType`
|
||||
and takes two constructor arguments: a `ActorSystem.Settings` object and
|
||||
a `Config` section. The latter is computed by obtaining the named
|
||||
configuration section from the actor system’s configuration, overriding its
|
||||
`id` key with the configuration path of the mailbox type and adding a
|
||||
fall-back to the default mailbox configuration section.
|
||||
|
||||
## Builtin Mailbox Implementations
|
||||
|
||||
Akka comes shipped with a number of mailbox implementations:
|
||||
|
||||
*
|
||||
**UnboundedMailbox** (default)
|
||||
* The default mailbox
|
||||
* Backed by a `java.util.concurrent.ConcurrentLinkedQueue`
|
||||
* Blocking: No
|
||||
* Bounded: No
|
||||
* Configuration name: `"unbounded"` or `"akka.dispatch.UnboundedMailbox"`
|
||||
*
|
||||
**SingleConsumerOnlyUnboundedMailbox**
|
||||
This queue may or may not be faster than the default one depending on your use-case—be sure to benchmark properly!
|
||||
* Backed by a Multiple-Producer Single-Consumer queue, cannot be used with `BalancingDispatcher`
|
||||
* Blocking: No
|
||||
* Bounded: No
|
||||
* Configuration name: `"akka.dispatch.SingleConsumerOnlyUnboundedMailbox"`
|
||||
*
|
||||
**NonBlockingBoundedMailbox**
|
||||
* Backed by a very efficient Multiple-Producer Single-Consumer queue
|
||||
* Blocking: No (discards overflowing messages into deadLetters)
|
||||
* Bounded: Yes
|
||||
* Configuration name: `"akka.dispatch.NonBlockingBoundedMailbox"`
|
||||
*
|
||||
**UnboundedControlAwareMailbox**
|
||||
* Delivers messages that extend `akka.dispatch.ControlMessage` with higher priority
|
||||
* Backed by two `java.util.concurrent.ConcurrentLinkedQueue`
|
||||
* Blocking: No
|
||||
* Bounded: No
|
||||
* Configuration name: "akka.dispatch.UnboundedControlAwareMailbox"
|
||||
*
|
||||
**UnboundedPriorityMailbox**
|
||||
* Backed by a `java.util.concurrent.PriorityBlockingQueue`
|
||||
* Delivery order for messages of equal priority is undefined - contrast with the UnboundedStablePriorityMailbox
|
||||
* Blocking: No
|
||||
* Bounded: No
|
||||
* Configuration name: "akka.dispatch.UnboundedPriorityMailbox"
|
||||
*
|
||||
**UnboundedStablePriorityMailbox**
|
||||
* Backed by a `java.util.concurrent.PriorityBlockingQueue` wrapped in an `akka.util.PriorityQueueStabilizer`
|
||||
* FIFO order is preserved for messages of equal priority - contrast with the UnboundedPriorityMailbox
|
||||
* Blocking: No
|
||||
* Bounded: No
|
||||
* Configuration name: "akka.dispatch.UnboundedStablePriorityMailbox"
|
||||
|
||||
Other bounded mailbox implementations which will block the sender if the capacity is reached and
|
||||
configured with non-zero `mailbox-push-timeout-time`.
|
||||
|
||||
@@@ note
|
||||
|
||||
The following mailboxes should only be used with zero `mailbox-push-timeout-time`.
|
||||
|
||||
@@@
|
||||
|
||||
* **BoundedMailbox**
|
||||
* Backed by a `java.util.concurrent.LinkedBlockingQueue`
|
||||
* Blocking: Yes if used with non-zero `mailbox-push-timeout-time`, otherwise No
|
||||
* Bounded: Yes
|
||||
* Configuration name: "bounded" or "akka.dispatch.BoundedMailbox"
|
||||
* **BoundedPriorityMailbox**
|
||||
* Backed by a `java.util.PriorityQueue` wrapped in an `akka.util.BoundedBlockingQueue`
|
||||
* Delivery order for messages of equal priority is undefined - contrast with the `BoundedStablePriorityMailbox`
|
||||
* Blocking: Yes if used with non-zero `mailbox-push-timeout-time`, otherwise No
|
||||
* Bounded: Yes
|
||||
* Configuration name: `"akka.dispatch.BoundedPriorityMailbox"`
|
||||
* **BoundedStablePriorityMailbox**
|
||||
* Backed by a `java.util.PriorityQueue` wrapped in an `akka.util.PriorityQueueStabilizer` and an `akka.util.BoundedBlockingQueue`
|
||||
* FIFO order is preserved for messages of equal priority - contrast with the BoundedPriorityMailbox
|
||||
* Blocking: Yes if used with non-zero `mailbox-push-timeout-time`, otherwise No
|
||||
* Bounded: Yes
|
||||
* Configuration name: "akka.dispatch.BoundedStablePriorityMailbox"
|
||||
* **BoundedControlAwareMailbox**
|
||||
* Delivers messages that extend `akka.dispatch.ControlMessage` with higher priority
|
||||
* Backed by two `java.util.concurrent.ConcurrentLinkedQueue` and blocking on enqueue if capacity has been reached
|
||||
* Blocking: Yes if used with non-zero `mailbox-push-timeout-time`, otherwise No
|
||||
* Bounded: Yes
|
||||
* Configuration name: "akka.dispatch.BoundedControlAwareMailbox"
|
||||
actors running on it. This can be configured as documented at [typed/mailboxes.md#requiring-a-message-queue-type-for-a-dispatcher]
|
||||
|
||||
## Mailbox configuration examples
|
||||
|
||||
|
|
@ -276,50 +137,6 @@ Scala
|
|||
Java
|
||||
: @@snip [DispatcherDocTest.java](/akka-docs/src/test/java/jdocs/dispatcher/DispatcherDocTest.java) { #control-aware-dispatcher }
|
||||
|
||||
## Creating your own Mailbox type
|
||||
|
||||
An example is worth a thousand quacks:
|
||||
|
||||
Scala
|
||||
: @@snip [MyUnboundedMailbox.scala](/akka-docs/src/test/scala/docs/dispatcher/MyUnboundedMailbox.scala) { #mailbox-marker-interface }
|
||||
|
||||
Java
|
||||
: @@snip [MyUnboundedMessageQueueSemantics.java](/akka-docs/src/test/java/jdocs/dispatcher/MyUnboundedMessageQueueSemantics.java) { #mailbox-marker-interface }
|
||||
|
||||
|
||||
Scala
|
||||
: @@snip [MyUnboundedMailbox.scala](/akka-docs/src/test/scala/docs/dispatcher/MyUnboundedMailbox.scala) { #mailbox-implementation-example }
|
||||
|
||||
Java
|
||||
: @@snip [MyUnboundedMailbox.java](/akka-docs/src/test/java/jdocs/dispatcher/MyUnboundedMailbox.java) { #mailbox-implementation-example }
|
||||
|
||||
And then you specify the FQCN of your MailboxType as the value of the "mailbox-type" in the dispatcher
|
||||
configuration, or the mailbox configuration.
|
||||
|
||||
@@@ note
|
||||
|
||||
Make sure to include a constructor which takes
|
||||
`akka.actor.ActorSystem.Settings` and `com.typesafe.config.Config`
|
||||
arguments, as this constructor is invoked reflectively to construct your
|
||||
mailbox type. The config passed in as second argument is that section from
|
||||
the configuration which describes the dispatcher or mailbox setting using
|
||||
this mailbox type; the mailbox type will be instantiated once for each
|
||||
dispatcher or mailbox setting using it.
|
||||
|
||||
@@@
|
||||
|
||||
You can also use the mailbox as a requirement on the dispatcher like this:
|
||||
|
||||
@@snip [DispatcherDocSpec.scala](/akka-docs/src/test/scala/docs/dispatcher/DispatcherDocSpec.scala) { #custom-mailbox-config-java }
|
||||
|
||||
Or by defining the requirement on your actor class like this:
|
||||
|
||||
Scala
|
||||
: @@snip [DispatcherDocSpec.scala](/akka-docs/src/test/scala/docs/dispatcher/DispatcherDocSpec.scala) { #require-mailbox-on-actor }
|
||||
|
||||
Java
|
||||
: @@snip [DispatcherDocTest.java](/akka-docs/src/test/java/jdocs/dispatcher/DispatcherDocTest.java) { #require-mailbox-on-actor }
|
||||
|
||||
## Special Semantics of `system.actorOf`
|
||||
|
||||
In order to make `system.actorOf` both synchronous and non-blocking while
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@ For advanced use cases it is also possible to defer mailbox selection to config
|
|||
|
||||
## Selecting what mailbox is used
|
||||
|
||||
To select mailbox for an actor use `MailboxSelector` to create a `Props` instance for spawning your actor:
|
||||
### Selecting a Mailbox Type for an Actor
|
||||
|
||||
To select a specific mailbox for an actor use `MailboxSelector` to create a `Props` instance for spawning your actor:
|
||||
|
||||
Scala
|
||||
: @@snip [MailboxDocSpec.scala](/akka-actor-typed-tests/src/test/scala/docs/akka/typed/MailboxDocSpec.scala) { #select-mailbox }
|
||||
|
|
@ -33,8 +35,182 @@ Scala
|
|||
Java
|
||||
: @@snip [MailboxDocTest.java](/akka-actor-typed-tests/src/test/java/jdocs/akka/typed/MailboxDocTest.java) { #select-mailbox }
|
||||
|
||||
`fromConfig` takes an absolute config path to a block defining the dispatcher in the config file like this:
|
||||
`fromConfig` takes an absolute config path to a block defining the dispatcher in the config file:
|
||||
|
||||
@@snip [MailboxDocSpec.scala](/akka-actor-typed-tests/src/test/resources/mailbox-config-sample.conf) { }
|
||||
|
||||
For more details on advanced mailbox config and custom mailbox implementations, see @ref[Classic Mailboxes](../mailboxes.md#builtin-mailbox-implementations).
|
||||
### Requiring a Message Queue Type for a Dispatcher
|
||||
|
||||
A dispatcher may also have a requirement for the mailbox type used by the
|
||||
actors running on it. An example is the @apidoc[BalancingDispatcher] which requires a
|
||||
message queue that is thread-safe for multiple concurrent consumers. Such a
|
||||
requirement is formulated within the dispatcher configuration section:
|
||||
|
||||
```
|
||||
my-dispatcher {
|
||||
mailbox-requirement = org.example.MyInterface
|
||||
}
|
||||
```
|
||||
|
||||
The given requirement names a class or interface which will then be ensured to
|
||||
be a supertype of the message queue's implementation. In case of a
|
||||
conflict—e.g. if the actor requires a mailbox type which does not satisfy this
|
||||
requirement—then actor creation will fail.
|
||||
|
||||
### How the Mailbox Type is Selected
|
||||
|
||||
When an actor is created, the `ActorRefProvider` first determines the
|
||||
dispatcher which will execute it. Then the mailbox is determined as follows:
|
||||
|
||||
1. If the actor's deployment configuration section contains a `mailbox` key,
|
||||
this refers to a configuration section describing the mailbox type.
|
||||
2. If the actor's `Props` contains a mailbox selection then that names a configuration section describing the
|
||||
mailbox type to be used. This needs to be an absolute config path,
|
||||
for example `myapp.special-mailbox`, and is not nested inside the `akka` namespace.
|
||||
3. If the dispatcher's configuration section contains a `mailbox-type` key
|
||||
the same section will be used to configure the mailbox type.
|
||||
4. If the actor requires a mailbox type as described above then the mapping for
|
||||
that requirement will be used to determine the mailbox type to be used; if
|
||||
that fails then the dispatcher's requirement—if any—will be tried instead.
|
||||
5. If the dispatcher requires a mailbox type as described above then the
|
||||
mapping for that requirement will be used to determine the mailbox type to
|
||||
be used.
|
||||
6. The default mailbox `akka.actor.default-mailbox` will be used.
|
||||
|
||||
### Default Mailbox
|
||||
|
||||
The default mailbox is used when the mailbox is not specified.
|
||||
This is an unbounded mailbox, backed by a
|
||||
`java.util.concurrent.ConcurrentLinkedQueue`.
|
||||
|
||||
`SingleConsumerOnlyUnboundedMailbox` is an even more efficient mailbox, and
|
||||
it can be used as the default mailbox, but it cannot be used with a BalancingDispatcher.
|
||||
|
||||
Configuration of `SingleConsumerOnlyUnboundedMailbox` as default mailbox:
|
||||
|
||||
```
|
||||
akka.actor.default-mailbox {
|
||||
mailbox-type = "akka.dispatch.SingleConsumerOnlyUnboundedMailbox"
|
||||
}
|
||||
```
|
||||
|
||||
### Which Configuration is passed to the Mailbox Type
|
||||
|
||||
Each mailbox type is implemented by a class which extends `MailboxType`
|
||||
and takes two constructor arguments: a `ActorSystem.Settings` object and
|
||||
a `Config` section. The latter is computed by obtaining the named
|
||||
configuration section from the `ActorSystem` configuration, overriding its
|
||||
`id` key with the configuration path of the mailbox type and adding a
|
||||
fall-back to the default mailbox configuration section.
|
||||
|
||||
## Mailbox Implementations
|
||||
|
||||
Akka ships with a number of mailbox implementations:
|
||||
|
||||
*
|
||||
**UnboundedMailbox** (default)
|
||||
* The default mailbox
|
||||
* Backed by a `java.util.concurrent.ConcurrentLinkedQueue`
|
||||
* Blocking: No
|
||||
* Bounded: No
|
||||
* Configuration name: `"unbounded"` or `"akka.dispatch.UnboundedMailbox"`
|
||||
*
|
||||
**SingleConsumerOnlyUnboundedMailbox**
|
||||
Depending on your use case, this queue may or may not be faster than the default one — be sure to benchmark properly!
|
||||
* Backed by a Multiple-Producer Single-Consumer queue, cannot be used with `BalancingDispatcher`
|
||||
* Blocking: No
|
||||
* Bounded: No
|
||||
* Configuration name: `"akka.dispatch.SingleConsumerOnlyUnboundedMailbox"`
|
||||
*
|
||||
**NonBlockingBoundedMailbox**
|
||||
* Backed by a very efficient Multiple-Producer Single-Consumer queue
|
||||
* Blocking: No (discards overflowing messages into deadLetters)
|
||||
* Bounded: Yes
|
||||
* Configuration name: `"akka.dispatch.NonBlockingBoundedMailbox"`
|
||||
*
|
||||
**UnboundedControlAwareMailbox**
|
||||
* Delivers messages that extend `akka.dispatch.ControlMessage` with higher priority
|
||||
* Backed by two `java.util.concurrent.ConcurrentLinkedQueue`
|
||||
* Blocking: No
|
||||
* Bounded: No
|
||||
* Configuration name: "akka.dispatch.UnboundedControlAwareMailbox"
|
||||
*
|
||||
**UnboundedPriorityMailbox**
|
||||
* Backed by a `java.util.concurrent.PriorityBlockingQueue`
|
||||
* Delivery order for messages of equal priority is undefined - contrast with the UnboundedStablePriorityMailbox
|
||||
* Blocking: No
|
||||
* Bounded: No
|
||||
* Configuration name: "akka.dispatch.UnboundedPriorityMailbox"
|
||||
*
|
||||
**UnboundedStablePriorityMailbox**
|
||||
* Backed by a `java.util.concurrent.PriorityBlockingQueue` wrapped in an `akka.util.PriorityQueueStabilizer`
|
||||
* FIFO order is preserved for messages of equal priority - contrast with the UnboundedPriorityMailbox
|
||||
* Blocking: No
|
||||
* Bounded: No
|
||||
* Configuration name: "akka.dispatch.UnboundedStablePriorityMailbox"
|
||||
|
||||
Other bounded mailbox implementations which will block the sender if the capacity is reached and
|
||||
configured with non-zero `mailbox-push-timeout-time`.
|
||||
|
||||
@@@ note
|
||||
|
||||
The following mailboxes should only be used with zero `mailbox-push-timeout-time`.
|
||||
|
||||
@@@
|
||||
|
||||
* **BoundedMailbox**
|
||||
* Backed by a `java.util.concurrent.LinkedBlockingQueue`
|
||||
* Blocking: Yes if used with non-zero `mailbox-push-timeout-time`, otherwise No
|
||||
* Bounded: Yes
|
||||
* Configuration name: "bounded" or "akka.dispatch.BoundedMailbox"
|
||||
* **BoundedPriorityMailbox**
|
||||
* Backed by a `java.util.PriorityQueue` wrapped in an `akka.util.BoundedBlockingQueue`
|
||||
* Delivery order for messages of equal priority is undefined - contrast with the `BoundedStablePriorityMailbox`
|
||||
* Blocking: Yes if used with non-zero `mailbox-push-timeout-time`, otherwise No
|
||||
* Bounded: Yes
|
||||
* Configuration name: `"akka.dispatch.BoundedPriorityMailbox"`
|
||||
* **BoundedStablePriorityMailbox**
|
||||
* Backed by a `java.util.PriorityQueue` wrapped in an `akka.util.PriorityQueueStabilizer` and an `akka.util.BoundedBlockingQueue`
|
||||
* FIFO order is preserved for messages of equal priority - contrast with the BoundedPriorityMailbox
|
||||
* Blocking: Yes if used with non-zero `mailbox-push-timeout-time`, otherwise No
|
||||
* Bounded: Yes
|
||||
* Configuration name: "akka.dispatch.BoundedStablePriorityMailbox"
|
||||
* **BoundedControlAwareMailbox**
|
||||
* Delivers messages that extend `akka.dispatch.ControlMessage` with higher priority
|
||||
* Backed by two `java.util.concurrent.ConcurrentLinkedQueue` and blocking on enqueue if capacity has been reached
|
||||
* Blocking: Yes if used with non-zero `mailbox-push-timeout-time`, otherwise No
|
||||
* Bounded: Yes
|
||||
* Configuration name: "akka.dispatch.BoundedControlAwareMailbox"
|
||||
|
||||
## Custom Mailbox type
|
||||
|
||||
The best way to show how to create your own Mailbox type is by example:
|
||||
|
||||
Scala
|
||||
: @@snip [MyUnboundedMailbox.scala](/akka-docs/src/test/scala/docs/dispatcher/MyUnboundedMailbox.scala) { #mailbox-marker-interface }
|
||||
|
||||
Java
|
||||
: @@snip [MyUnboundedMessageQueueSemantics.java](/akka-docs/src/test/java/jdocs/dispatcher/MyUnboundedMessageQueueSemantics.java) { #mailbox-marker-interface }
|
||||
|
||||
|
||||
Scala
|
||||
: @@snip [MyUnboundedMailbox.scala](/akka-docs/src/test/scala/docs/dispatcher/MyUnboundedMailbox.scala) { #mailbox-implementation-example }
|
||||
|
||||
Java
|
||||
: @@snip [MyUnboundedMailbox.java](/akka-docs/src/test/java/jdocs/dispatcher/MyUnboundedMailbox.java) { #mailbox-implementation-example }
|
||||
|
||||
And then you specify the FQCN of your MailboxType as the value of the "mailbox-type" in the dispatcher
|
||||
configuration, or the mailbox configuration.
|
||||
|
||||
@@@ note
|
||||
|
||||
Make sure to include a constructor which takes
|
||||
`akka.actor.ActorSystem.Settings` and `com.typesafe.config.Config`
|
||||
arguments, as this constructor is invoked reflectively to construct your
|
||||
mailbox type. The config passed in as second argument is that section from
|
||||
the configuration which describes the dispatcher or mailbox setting using
|
||||
this mailbox type; the mailbox type will be instantiated once for each
|
||||
dispatcher or mailbox setting using it.
|
||||
|
||||
@@@
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue