Merge akka-docs/paradox/scala/actors.md and java/actors.md (#23079)

* Identical contents in scala/actors.md and java/actors.md
* Replace java/actors.md with a symlink to scala/actors.md
This commit is contained in:
Richard Imaoka 2017-06-03 22:34:22 +09:00 committed by Arnout Engelen
parent fb3e42f2e8
commit c569bdbc7c
5 changed files with 489 additions and 1188 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
../scala/actors.md

View file

@ -1,37 +0,0 @@
# Java 8 and Scala Compatibility
Akka requires that you have [Java 8](http://www.oracle.com/technetwork/java/javase/downloads/index.html) or
later installed on your machine.
## Java 8 types
Starting with Akka 2.4.2 we have begun to introduce Java 8 types (most
prominently `java.util.concurrent.CompletionStage` and
`java.util.Optional`) where that was possible without breaking binary or
source compatibility. Where this was not possible (for example in the return
type of `ActorSystem.terminate()`) please refer to the
`scala-java8-compat` library that allows easy conversion between the Scala
and Java counterparts. The artifact can be included in Maven builds using:
```
<dependency>
<groupId>org.scala-lang.modules</groupId>
<artifactId>scala-java8-compat_2.11</artifactId>
<version>0.7.0</version>
</dependency>
```
We will only be able to seamlessly integrate all functional interfaces once
we can rely on Scala 2.12 to provide full interoperability—this will mean that
Scala users can directly implement Java Functional Interfaces using lambda syntax
as well as that Java users can directly implement Scala functions using lambda
syntax.
## Do not use -optimize Scala compiler flag
@@@ warning
Akka has not been compiled or tested with -optimize Scala compiler flag.
Strange behavior has been reported by users that have tried it.
@@@

View file

@ -0,0 +1 @@
../scala/scala-compat.md

View file

@ -24,15 +24,38 @@ and it may also help to read @ref:[Actor References, Paths and Addresses](genera
### Defining an Actor class
@@@ div { .group-scala }
Actors are implemented by extending the `Actor` base trait and implementing the
`receive` method. The `receive` method should define a series of case
statements (which has the type `PartialFunction[Any, Unit]`) that defines
which messages your Actor can handle, using standard Scala pattern matching,
along with the implementation of how the messages should be processed.
@@@
@@@ div { .group-java }
Actor classes are implemented by extending the `AbstractActor` class and setting
the “initial behavior” in the constructor by calling the `receive` method in
the `AbstractActor`.
The argument to the `receive` method is a `PartialFunction<Object,BoxedUnit>`
that defines which messages your Actor can handle, along with the implementation of
how the messages should be processed.
Don't let the type signature scare you. To allow you to easily build up a partial
function there is a builder named `ReceiveBuilder` that you can use.
@@@
Here is an example:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #imports1 #my-actor }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #imports1 #my-actor }
Java
: @@snip [MyActor.java]($code$/java/jdocs/actor/MyActor.java) { #imports #my-actor }
Please note that the Akka Actor `receive` message loop is exhaustive, which
is different compared to Erlang and the late Scala Actors. This means that you
@ -46,17 +69,19 @@ Note further that the return type of the behavior defined above is `Unit`; if
the actor shall reply to the received message then this must be done explicitly
as explained below.
The result of the `receive` method is a partial function object, which is
The @scala[result of] @java[argument to] the `receive` method is a partial function object, which is
stored within the actor as its “initial behavior”, see [Become/Unbecome](#become-unbecome) for
further information on changing the behavior of an actor after its
construction.
@@@ div { .group-scala }
#### Here is another example that you can edit and run in the browser:
@@fiddle [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #fiddle_code height=400px extraParams=theme=light&layout=v75 cssStyle=width:100%; }
@@@
### Props
`Props` is a configuration class to specify options for the creation
@ -65,7 +90,12 @@ creating an actor including associated deployment information (e.g. which
dispatcher to use, see more below). Here are some examples of how to create a
`Props` instance.
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #creating-props }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #creating-props }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #import-props #creating-props }
The second variant shows how to pass constructor arguments to the
`Actor` being created, but it should only be used outside of actors as
@ -77,7 +107,7 @@ verified during construction of the `Props` object, resulting in an
`IllegalArgumentException` if no or multiple matching constructors are
found.
@@@ note
@@@ note { .group-scala }
The recommended approach to create the actor `Props` is not supported
for cases when the actor constructor takes value classes as arguments.
@ -85,8 +115,11 @@ for cases when the actor constructor takes value classes as arguments.
@@@
#### Dangerous Variants
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #creating-props-deprecated }
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #creating-props-deprecated }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #creating-props-deprecated }
This method is not recommended to be used within another actor because it
encourages to close over the enclosing scope, resulting in non-serializable
@ -97,7 +130,7 @@ is completely fine.
There were two use-cases for these methods: passing constructor arguments to
the actor—which is solved by the newly introduced
`Props.apply(clazz, args)` method above or the recommended practice
@scala[`Props.apply(clazz, args)`] @java[`Props.create(clazz, args)`] method above or the recommended practice
below—and creating actors “on the spot” as anonymous classes. The latter should
be solved by making these actors named classes instead (if they are not
declared within a top-level `object` then the enclosing instances `this`
@ -110,6 +143,8 @@ encapsulation. Never pass an actors `this` reference into `Props`!
@@@
@@@ div { .group-scala }
#### Edge cases
There are two edge cases in actor creation with `Props`:
@ -130,22 +165,33 @@ no matching constructor could be found.
The next section explains the recommended ways to create `Actor` props in a way,
which simultaneously safe-guards against these edge cases.
@@@
#### Recommended Practices
It is a good idea to provide factory methods on the companion object of each
`Actor` which help keeping the creation of suitable `Props` as
close to the actor definition as possible. This also avoids the pitfalls
associated with using the `Props.apply(...)` method which takes a by-name
associated with using the @scala[`Props.apply(...)`] @java[ `Props.create(...)`] method which takes a by-name
argument, since within a companion object the given code block will not retain
a reference to its enclosing scope:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #props-factory }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #props-factory }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #props-factory }
Another good practice is to declare what messages an Actor can receive
in the companion object of the Actor, which makes easier
to know what it can receive:
@scala[in the companion object of the Actor]
@java[as close to the actor definition as possible (e.g. as static classes inside the Actor or using other suitable class)],
which makes easier to know what it can receive:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #messages-in-companion }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #messages-in-companion }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #messages-in-companion }
### Creating Actors with Props
@ -153,13 +199,21 @@ Actors are created by passing a `Props` instance into the
`actorOf` factory method which is available on `ActorSystem` and
`ActorContext`.
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #system-actorOf }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #system-actorOf }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #import-actorRef }
Using the `ActorSystem` will create top-level actors, supervised by the
actor systems provided guardian actor, while using an actors context will
create a child actor.
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #context-actorOf }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #context-actorOf }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #context-actorOf }
It is recommended to create a hierarchy of children, grand-children and so on
such that it fits the logical failure-handling structure of the application,
@ -181,6 +235,8 @@ another child to the same parent an `InvalidActorNameException` is thrown.
Actors are automatically started asynchronously when created.
@@@ div { .group-scala }
#### Value classes as constructor arguments
The recommended way to instantiate actor props uses reflection at runtime
@ -192,19 +248,25 @@ calling the constructor manually:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #actor-with-value-class-argument }
@@@
### Dependency Injection
If your Actor has a constructor that takes parameters then those need to
If your `Actor` has a constructor that takes parameters then those need to
be part of the `Props` as well, as described [above](Props_). But there
are cases when a factory method must be used, for example when the actual
constructor arguments are determined by a dependency injection framework.
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #creating-indirectly }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #creating-indirectly }
Java
: @@snip [DependencyInjectionDocTest.java]($code$/java/jdocs/actor/DependencyInjectionDocTest.java) { #import #creating-indirectly }
@@@ warning
You might be tempted at times to offer an `IndirectActorProducer`
which always returns the same instance, e.g. by using a `lazy val`. This is
which always returns the same instance, e.g. by using a @scala[`lazy val`.] @java[static field.] This is
not supported, as it goes against the meaning of an actor restart, which is
described here: @ref:[What Restarting Means](general/supervision.md#supervision-restart).
@ -226,7 +288,14 @@ cannot do: receiving multiple replies (e.g. by subscribing an `ActorRef`
to a notification service) and watching other actors lifecycle. For these
purposes there is the `Inbox` class:
@@snip [ActorDSLSpec.scala]($akka$/akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala) { #inbox }
Scala
: @@snip [ActorDSLSpec.scala]($akka$/akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala) { #inbox }
Java
: @@snip [InboxDocTest.java]($code$/java/jdocs/actor/InboxDocTest.java) { #inbox }
@@@ div { .group-scala }
There is an implicit conversion from inbox to actor reference which means that
in this example the sender reference will be that of the actor hidden away
@ -235,10 +304,24 @@ Watching an actor is quite simple as well:
@@snip [ActorDSLSpec.scala]($akka$/akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala) { #watch }
@@@
@@@ div { .group-java }
The `send` method wraps a normal `tell` and supplies the internal
actors reference as the sender. This allows the reply to be received on the
last line. Watching an actor is quite simple as well:
@@snip [InboxDocTest.java]($code$/java/jdocs/actor/InboxDocTest.java) { #watch }
@@@
## Actor API
The `Actor` trait defines only one abstract method, the above mentioned
`receive`, which implements the behavior of the actor.
@scala[The `Actor` trait defines only one abstract method, the above mentioned
`receive`, which implements the behavior of the actor.]
@java[The `AbstractActor` class defines a method called `receive`,
that is used to set the “initial behavior” of the actor.]
If the current actor behavior does not match a received message,
`unhandled` is called, which by default publishes an
@ -248,11 +331,13 @@ systems event stream (set configuration item
actual Debug messages).
In addition, it offers:
* `self` reference to the `ActorRef` of the actor
* `sender` reference sender Actor of the last received message, typically used as described in [Actor.Reply](#actor-reply)
*
`supervisorStrategy` user overridable definition the strategy to use for supervising child actors
* @scala[`self`] @java[`getSelf()`] reference to the `ActorRef` of the actor
* @scala[`sender`] @java[`getSender()`] reference sender Actor of the last received message, typically used as described in
@scala[[Actor.Reply](#actor-reply)]
@java[[LambdaActor.Reply](#lambdaactor-reply)]
* @scala[`supervisorStrategy`] @java[`supervisorStrategy()`] user overridable definition the strategy to use for supervising child actors
This strategy is typically declared inside the actor in order to have access
to the actors internal state within the decider function: since failure is
communicated as a message sent to the supervisor and processed like other
@ -261,26 +346,33 @@ within the actor are available, as is the `sender` reference (which will
be the immediate child reporting the failure; if the original failure
occurred within a distant descendant it is still reported one level up at a
time).
*
`context` exposes contextual information for the actor and the current message, such as:
* @scala[`context`] @java[`getContext()`] exposes contextual information for the actor and the current message, such as:
* factory methods to create child actors (`actorOf`)
* system that the actor belongs to
* parent supervisor
* supervised children
* lifecycle monitoring
* hotswap behavior stack as described in [Actor.HotSwap](#actor-hotswap)
* hotswap behavior stack as described in @scala[[Actor.HotSwap](#actor-hotswap)] @java[[Become/Unbecome](#actor-hotswap)]
@@@ div { .group-scala }
You can import the members in the `context` to avoid prefixing access with `context.`
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #import-context }
@@@
The remaining visible methods are user-overridable life-cycle hooks which are
described in the following:
@@snip [Actor.scala]($akka$/akka-actor/src/main/scala/akka/actor/Actor.scala) { #lifecycle-hooks }
Scala
: @@snip [Actor.scala]($akka$/akka-actor/src/main/scala/akka/actor/Actor.scala) { #lifecycle-hooks }
The implementations shown above are the defaults provided by the `Actor`
trait.
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #lifecycle-callbacks }
The implementations shown above are the defaults provided by the @scala[`Actor` trait.] @java[`AbstractActor` class.]
<a id="actor-lifecycle"></a>
### Actor Lifecycle
@ -338,7 +430,11 @@ termination (see [Stopping Actors](#stopping-actors)). This service is provided
Registering a monitor is easy:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #watch }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #watch }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #import-terminated #watch }
It should be noted that the `Terminated` message is generated
independent of the order in which registration and termination occur.
@ -363,7 +459,11 @@ no `Terminated` message for that actor will be processed anymore.
Right after starting the actor, its `preStart` method is invoked.
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #preStart }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #preStart }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #preStart }
This method is called when the actor is first created. During restarts it is
called by the default implementation of `postRestart`, which means that
@ -436,7 +536,11 @@ actors may look up other actors by specifying absolute or relative
paths—logical or physical—and receive back an `ActorSelection` with the
result:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #selection-local }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #selection-local }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #selection-local }
@@@ note
@ -464,14 +568,18 @@ structure, i.e. the supervisor.
The path elements of an actor selection may contain wildcard patterns allowing for
broadcasting of messages to that section:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #selection-wildcard }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #selection-wildcard }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #selection-wildcard }
Messages can be sent via the `ActorSelection` and the path of the
`ActorSelection` is looked up when delivering each message. If the selection
does not match any actors the message will be dropped.
To acquire an `ActorRef` for an `ActorSelection` you need to send
a message to the selection and use the `sender()` reference of the reply from
a message to the selection and use the @scala[`sender()`] @java[`getSender()`] reference of the reply from
the actor. There is a built-in `Identify` message that all Actors will
understand and automatically reply to with a `ActorIdentity` message
containing the `ActorRef`. This message is handled specially by the
@ -480,17 +588,26 @@ actors which are traversed in the sense that if a concrete name lookup fails
negative result is generated. Please note that this does not mean that delivery
of that reply is guaranteed, it still is a normal message.
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #identify }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #identify }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #import-identify #identify }
You can also acquire an `ActorRef` for an `ActorSelection` with
the `resolveOne` method of the `ActorSelection`. It returns a `Future`
of the matching `ActorRef` if such an actor exists. It is completed with
of the matching `ActorRef` if such an actor exists. @java[(see also
@ref:[Java 8 and Scala Compatibility](scala-compat.md) for Java compatibility).] It is completed with
failure [[akka.actor.ActorNotFound]] if no such actor exists or the identification
didn't complete within the supplied *timeout*.
didn't complete within the supplied `timeout`.
Remote actor addresses may also be looked up, if @ref:[remoting](remoting.md) is enabled:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #selection-remote }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #selection-remote }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #selection-remote }
An example demonstrating actor look-up is given in @ref:[Remoting Sample](remoting.md#remote-sample).
@ -498,32 +615,31 @@ An example demonstrating actor look-up is given in @ref:[Remoting Sample](remoti
@@@ warning { title=IMPORTANT }
Messages can be any kind of object but have to be immutable. Scala cant enforce
immutability (yet) so this has to be by convention. Primitives like String, Int,
Messages can be any kind of object but have to be immutable. @scala[Scala] @java[Akka] cant enforce
immutability (yet) so this has to be by convention. @scala[Primitives like String, Int,
Boolean are always immutable. Apart from these the recommended approach is to
use Scala case classes which are immutable (if you dont explicitly expose the
state) and works great with pattern matching at the receiver side.
state) and works great with pattern matching at the receiver side.]
@@@
Here is an example:
Here is an @scala[example:] @java[example of an immutable message:]
```scala
// define the case class
case class Register(user: User)
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #immutable-message-definition #immutable-message-instantiation }
Java
: @@snip [ImmutableMessage.java]($code$/java/jdocs/actor/ImmutableMessage.java) { #immutable-message }
// create a new case class message
val message = Register(user)
```
## Send messages
Messages are sent to an Actor through one of the following methods.
* `!` means “fire-and-forget”, e.g. send a message asynchronously and return
immediately. Also known as `tell`.
* `?` sends a message asynchronously and returns a `Future`
representing a possible reply. Also known as `ask`.
* @scala[`!`] @java[`tell` ] means “fire-and-forget”, e.g. send a message asynchronously and return
immediately. @scala[Also known as `tell`.]
* @scala[`?`] @java[`ask`] sends a message asynchronously and returns a `Future`
representing a possible reply. @scala[Also known as `ask`].
Message ordering is guaranteed on a per-sender basis.
@ -536,13 +652,27 @@ remoting. So always prefer `tell` for performance, and only `ask` if you must.
@@@
@@@ div { .group-java }
In all these methods you have the option of passing along your own `ActorRef`.
Make it a practice of doing so because it will allow the receiver actors to be able to respond
to your message, since the sender reference is sent along with the message.
@@@
<a id="actors-tell-sender"></a>
### Tell: Fire-forget
This is the preferred way of sending messages. No blocking waiting for a
message. This gives the best concurrency and scalability characteristics.
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #tell }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #tell }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #tell }
@@@ div { .group-scala }
If invoked from within an Actor, then the sending actor reference will be
implicitly passed along with the message and available to the receiving Actor
@ -552,28 +682,55 @@ to reply to the original sender, by using `sender() ! replyMsg`.
If invoked from an instance that is **not** an Actor the sender will be
`deadLetters` actor reference by default.
@@@
@@@ div { .group-java }
The sender reference is passed along with the message and available within the
receiving actor via its `getSender()` method while processing this
message. Inside of an actor it is usually `getSelf()` who shall be the
sender, but there can be cases where replies shall be routed to some other
actor—e.g. the parent—in which the second argument to `tell` would be a
different one. Outside of an actor and if no reply is needed the second
argument can be `null`; if a reply is needed outside of an actor you can use
the ask-pattern described next..
@@@
<a id="actors-ask"></a>
### Ask: Send-And-Receive-Future
The `ask` pattern involves actors as well as futures, hence it is offered as
a use pattern rather than a method on `ActorRef`:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #ask-pipeTo }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #ask-pipeTo }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #import-ask #ask-pipe }
This example demonstrates `ask` together with the `pipeTo` pattern on
futures, because this is likely to be a common combination. Please note that
all of the above is completely non-blocking and asynchronous: `ask` produces
a `Future`, three of which are composed into a new future using the
for-comprehension and then `pipeTo` installs an `onComplete`-handler on the
future to affect the submission of the aggregated `Result` to another
actor.
a `Future`, @scala[three] @java[two] of which are composed into a new future using the
@scala[for-comprehension and then `pipeTo` installs an `onComplete`-handler on the future to affect]
@java[`Futures.sequence` and `map` methods and then `pipe` installs an `onComplete`-handler on the future to effect]
the submission of the aggregated `Result` to another actor.
Using `ask` will send a message to the receiving Actor as with `tell`, and
the receiving actor must reply with `sender() ! reply` in order to complete the
returned `Future` with a value. The `ask` operation involves creating
the receiving actor must reply with @scala[`sender() ! reply`] @java[`getSender().tell(reply, getSelf())` ] in order to
complete the returned `Future` with a value. The `ask` operation involves creating
an internal actor for handling this reply, which needs to have a timeout after
which it is destroyed in order not to leak resources; see more below.
@@@ note { .group-java }
A variant of the `ask` pattern that returns a `CompletionStage` instead of a Scala `Future`
is available in the `akka.pattern.PatternsCS` object.
@@@
@@@ warning
To complete the future with an exception you need send a Failure message to the sender.
@ -581,11 +738,17 @@ This is *not done automatically* when an actor throws an exception while process
@@@
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #reply-exception }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #reply-exception }
If the actor does not complete the future, it will expire after the timeout
period, completing it with an `AskTimeoutException`. The timeout is
taken from one of the following locations in order of precedence:
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #reply-exception }
If the actor does not complete the future, it will expire after the timeout period,
@scala[completing it with an `AskTimeoutException`. The timeout is taken from one of the following locations in order of precedence:]
@java[specified as parameter to the `ask` method; this will complete the `Future` with an `AskTimeoutException`.]
@@@ div { .group-scala }
1. explicitly given timeout as in:
@ -595,6 +758,8 @@ taken from one of the following locations in order of precedence:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #using-implicit-timeout }
@@@
See @ref:[Futures](futures.md) for more information on how to await or query a
future.
@ -604,7 +769,7 @@ you a way to avoid blocking.
@@@ warning
When using future callbacks, such as `onComplete`, `onSuccess`, and `onFailure`,
When using future callbacks, @scala[such as `onComplete`, `onSuccess`, and `onFailure`,]
inside actors you need to carefully avoid closing over
the containing actors reference, i.e. do not call methods or access mutable state
on the enclosing actor from within the callback. This would break the actor
@ -622,51 +787,119 @@ original sender address/reference is maintained even though the message is going
through a 'mediator'. This can be useful when writing actors that work as
routers, load-balancers, replicators etc.
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #forward }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #forward }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #forward }
## Receive messages
An Actor has to implement the `receive` method to receive messages:
@@snip [Actor.scala]($akka$/akka-actor/src/main/scala/akka/actor/Actor.scala) { #receive }
An Actor has to
@scala[implement the `receive` method to receive messages:]
@java[define its initial receive behavior by implementing the `createReceive` method in the `AbstractActor`:]
Scala
: @@snip [Actor.scala]($akka$/akka-actor/src/main/scala/akka/actor/Actor.scala) { #receive }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #createReceive }
@@@ div { .group-scala }
This method returns a `PartialFunction`, e.g. a match/case clause in
which the message can be matched against the different case clauses using Scala
pattern matching. Here is an example:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #imports1 #my-actor }
@@@
@@@ div { .group-java }
The return type is `AbstractActor.Receive` that defines which messages your Actor can handle,
along with the implementation of how the messages should be processed.
You can build such behavior with a builder named `ReceiveBuilder`. Here is an example:
@@@
@Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #imports1 #my-actor }
@Java
: @@snip [MyActor.java]($code$/java/jdocs/actor/MyActor.java) { #imports #my-actor }
@@@ div { .group-java }
In case you want to provide many `match` cases but want to avoid creating a long call
trail, you can split the creation of the builder into multiple statements as in the example:
@@snip [GraduallyBuiltActor.java]($code$/java/jdocs/actor/GraduallyBuiltActor.java) { #imports #actor }
Using small methods is a good practice, also in actors. It's recommended to delegate the
actual work of the message processing to methods instead of defining a huge `ReceiveBuilder`
with lots of code in each lambda. A well structured actor can look like this:
@@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #well-structured }
That has benefits such as:
* easier to see what kind of messages the actor can handle
* readable stack traces in case of exceptions
* works better with performance profiling tools
* Java HotSpot has a better opportunity for making optimizations
The `Receive` can be implemented in other ways than using the `ReceiveBuilder` since it in the
end is just a wrapper around a Scala `PartialFunction`. In Java, you can implement `PartialFunction` by
extending `AbstractPartialFunction`. For example, one could implement an adapter
to [Javaslang Pattern Matching DSL](http://www.javaslang.io/javaslang-jdocs/#_pattern_matching).
If the validation of the `ReceiveBuilder` match logic turns out to be a bottleneck for some of your
actors you can consider to implement it at lower level by extending `UntypedAbstractActor` instead
of `AbstractActor`. The partial functions created by the `ReceiveBuilder` consist of multiple lambda
expressions for every match statement, where each lambda is referencing the code to be run. This is something
that the JVM can have problems optimizing and the resulting code might not be as performant as the
untyped version. When extending `UntypedAbstractActor` each message is received as an untyped
`Object` and you have to inspect and cast it to the actual message type in other ways, like this:
@@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #optimized }
@@@
<a id="actor-reply"></a>
## Reply to messages
If you want to have a handle for replying to a message, you can use
`sender()`, which gives you an ActorRef. You can reply by sending to
that ActorRef with `sender() ! replyMsg`. You can also store the ActorRef
@scala[`sender()`] @java[`getSender()`], which gives you an ActorRef. You can reply by sending to
that ActorRef with @scala[`sender() ! replyMsg`.] @java[`getSender().tell(replyMsg, getSelf())`.] You can also store the ActorRef
for replying later, or passing on to other actors. If there is no sender (a
message was sent without an actor or future context) then the sender
defaults to a 'dead-letter' actor ref.
```scala
case request =>
val result = process(request)
sender() ! result // will have dead-letter actor as default
```
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #reply-without-sender }
Java
: @@snip [MyActor.java]($code$/java/jdocs/actor/MyActor.java) { #reply }
## Receive timeout
The *ActorContext* `setReceiveTimeout` defines the inactivity timeout after which
the sending of a *ReceiveTimeout* message is triggered.
When specified, the receive function should be able to handle an *akka.actor.ReceiveTimeout* message.
The `ActorContext` `setReceiveTimeout` defines the inactivity timeout after which
the sending of a `ReceiveTimeout` message is triggered.
When specified, the receive function should be able to handle an `akka.actor.ReceiveTimeout` message.
1 millisecond is the minimum supported timeout.
Please note that the receive timeout might fire and enqueue the *ReceiveTimeout* message right after
Please note that the receive timeout might fire and enqueue the `ReceiveTimeout` message right after
another message was enqueued; hence it is **not guaranteed** that upon reception of the receive
timeout there must have been an idle period beforehand as configured via this method.
Once set, the receive timeout stays in effect (i.e. continues firing repeatedly after inactivity
periods). Pass in *Duration.Undefined* to switch off this feature.
periods). Pass in `Duration.Undefined` to switch off this feature.
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #receive-timeout }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #receive-timeout }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #receive-timeout }
Messages marked with `NotInfluenceReceiveTimeout` will not reset the timer. This can be useful when
`ReceiveTimeout` should be fired by external inactivity but not influenced by internal activity,
@ -681,7 +914,12 @@ the actor itself or child actors and the system for stopping top level actors. T
termination of the actor is performed asynchronously, i.e. `stop` may return before
the actor is stopped.
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #stoppingActors-actor }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #stoppingActors-actor }
Java
: @@snip [MyStoppingActor.java]($code$/java/jdocs/actor/MyStoppingActor.java) { #my-stopping-actor }
Processing of the current message, if any, will continue before the actor is stopped,
but additional messages in the mailbox will not be processed. By default these
@ -707,7 +945,11 @@ whole system.
The `postStop()` hook is invoked after an actor is fully stopped. This
enables cleaning up of resources:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #postStop }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #postStop }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #postStop }
@@@ note
@ -727,14 +969,28 @@ stop the actor when the message is processed. `PoisonPill` is enqueued as
ordinary messages and will be handled after messages that were already queued
in the mailbox.
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #poison-pill }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #poison-pill }
### Graceful Stop
`gracefulStop` is useful if you need to wait for termination or compose ordered
termination of several actors:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #gracefulStop }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #gracefulStop }
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #gracefulStop-actor }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #import-gracefulStop #gracefulStop }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #gracefulStop-actor }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #gracefulStop-actor }
When `gracefulStop()` returns successfully, the actors `postStop()` hook
will have been executed: there exists a happens-before edge between the end of
@ -777,9 +1033,13 @@ The phases are ordered with [topological](https://en.wikipedia.org/wiki/Topologi
Tasks can be added to a phase with:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #coordinated-shutdown-addTask }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #coordinated-shutdown-addTask }
The returned `Future[Done]` should be completed when the task is completed. The task name parameter
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #coordinated-shutdown-addTask }
The returned @scala[`Future[Done]`] @java[`CompletionStage<Done>`] should be completed when the task is completed. The task name parameter
is only used for debugging/logging.
Tasks added to the same phase are executed in parallel without any ordering assumptions.
@ -793,12 +1053,16 @@ Tasks should typically be registered as early as possible after system startup.
the coordinated shutdown tasks that have been registered will be performed but tasks that are
added too late will not be run.
To start the coordinated shutdown process you can invoke `run` on the `CoordinatedShutdown`
To start the coordinated shutdown process you can invoke @scala[`run`] @java[`runAll`] on the `CoordinatedShutdown`
extension:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #coordinated-shutdown-run }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #coordinated-shutdown-run }
It's safe to call the `run` method multiple times. It will only run once.
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #coordinated-shutdown-run }
It's safe to call the @scala[`run`] @java[`runAll`] method multiple times. It will only run once.
That also means that the `ActorSystem` will be terminated in the last phase. By default, the
JVM is not forcefully stopped (it will be stopped if all non-daemon threads have been terminated).
@ -825,7 +1089,11 @@ If you have application specific JVM shutdown hooks it's recommended that you re
`CoordinatedShutdown` so that they are running before Akka internal shutdown hooks, e.g.
those shutting down Akka Remoting (Artery).
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #coordinated-shutdown-jvm-hook }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #coordinated-shutdown-jvm-hook }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #coordinated-shutdown-jvm-hook }
For some tests it might be undesired to terminate the `ActorSystem` via `CoordinatedShutdown`.
You can disable that by adding the following to the configuration of the `ActorSystem` that is
@ -845,7 +1113,7 @@ akka.cluster.run-coordinated-shutdown-when-down = off
Akka supports hotswapping the Actors message loop (e.g. its implementation) at
runtime: invoke the `context.become` method from within the Actor.
`become` takes a `PartialFunction[Any, Unit]` that implements the new
`become` takes a @scala[`PartialFunction[Any, Unit]`] @java[`PartialFunction<Object, BoxedUnit>`] that implements the new
message handler. The hotswapped code is kept in a Stack which can be pushed and
popped.
@ -857,11 +1125,16 @@ Please note that the actor will revert to its original behavior when restarted b
To hotswap the Actor behavior using `become`:
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #hot-swap-actor }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #hot-swap-actor }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #hot-swap-actor }
This variant of the `become` method is useful for many different things,
such as to implement a Finite State Machine (FSM, for an example see [Dining
Hakkers](http://www.lightbend.com/activator/template/akka-sample-fsm-scala)). It will replace the current behavior (i.e. the top of the behavior
such as to implement a Finite State Machine (FSM, for an example see @scala[[Dining
Hakkers](http://www.lightbend.com/activator/template/akka-sample-fsm-scala)).] @java[[Dining
Hakkers](http://www.lightbend.com/activator/template/akka-sample-fsm-java-lambda)).] It will replace the current behavior (i.e. the top of the behavior
stack), which means that you do not use `unbecome`, instead always the
next behavior is explicitly installed.
@ -871,7 +1144,11 @@ of “pop” operations (i.e. `unbecome`) matches the number of “push” ones
in the long run, otherwise this amounts to a memory leak (which is why this
behavior is not the default).
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #swapper }
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #swapper }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #swapper }
### Encoding Scala Actors nested receives without accidentally leaking memory
@ -880,27 +1157,43 @@ See this @extref[Unnested receive example](github:akka-docs/src/test/scala/docs/
<a id="stash"></a>
## Stash
The *Stash* trait enables an actor to temporarily stash away messages
The @scala[`Stash` trait] @java[`AbstractActorWithStash` class] enables an actor to temporarily stash away messages
that can not or should not be handled using the actor's current
behavior. Upon changing the actor's message handler, i.e., right
before invoking `context.become` or `context.unbecome`, all
before invoking @scala[`context.become` or `context.unbecome`] @java[`getContext().become()` or `getContext().unbecome()`], all
stashed messages can be "unstashed", thereby prepending them to the actor's
mailbox. This way, the stashed messages can be processed in the same
order as they have been received originally.
order as they have been received originally. @java[An actor that extends
`AbstractActorWithStash` will automatically get a deque-based mailbox.]
@@@ note
@@@ note { .group-scala }
The trait `Stash` extends the marker trait
`RequiresMessageQueue[DequeBasedMessageQueueSemantics]` which
requests the system to automatically choose a deque based
mailbox implementation for the actor. If you want more control over the
mailbox implementation for the actor. If you want more
control over the
mailbox, see the documentation on mailboxes: @ref:[Mailboxes](mailboxes.md).
@@@
Here is an example of the `Stash` in action:
@@@ note { .group-java }
@@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #stash }
The abstract class `AbstractActorWithStash` implements the marker
interface `RequiresMessageQueue<DequeBasedMessageQueueSemantics>`
which requests the system to automatically choose a deque based
mailbox implementation for the actor. If you want more
control over the mailbox, see the documentation on mailboxes: @ref:[Mailboxes](mailboxes.md).
@@@
Here is an example of the @scala[`Stash`] @java[`AbstractActorWithStash` class] in action:
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #stash }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #stash }
Invoking `stash()` adds the current message (the message that the
actor received last) to the actor's stash. It is typically invoked
@ -924,7 +1217,7 @@ The stash is backed by a `scala.collection.immutable.Vector`. As a
result, even a very large number of messages may be stashed without a
major impact on performance.
@@@ warning
@@@ warning { .group-scala }
Note that the `Stash` trait must be mixed into (a subclass of) the
`Actor` trait before any trait/class that overrides the `preRestart`
@ -935,14 +1228,14 @@ callback. This means it's not possible to write
Note that the stash is part of the ephemeral actor state, unlike the
mailbox. Therefore, it should be managed like other parts of the
actor's state which have the same property. The `Stash` traits
actor's state which have the same property. The @scala[`Stash` traits] @java[`AbstractActorWithStash`]
implementation of `preRestart` will call `unstashAll()`, which is
usually the desired behavior.
@@@ note
If you want to enforce that your actor can only work with an unbounded stash,
then you should use the `UnboundedStash` trait instead.
then you should use the @scala[`UnboundedStash` trait] @java[`AbstractActorWithUnboundedStash` class] instead.
@@@
@ -957,10 +1250,11 @@ See @ref:[What Supervision Means](general/supervision.md#supervision-directives)
Use `Kill` like this:
```scala
// kill the 'victim' actor
victim ! Kill
```
Scala
: @@snip [ActorDocSpec.scala]($code$/scala/docs/actor/ActorDocSpec.scala) { #kill }
Java
: @@snip [ActorDocTest.java]($code$/java/jdocs/actor/ActorDocTest.java) { #kill }
## Actors and exceptions
@ -990,6 +1284,8 @@ supervision process is started (see @ref:[supervision](general/supervision.md)).
supervisors decision the actor is resumed (as if nothing happened), restarted
(wiping out its internal state and starting from scratch) or terminated.
@@@ div { .group-scala }
## Extending Actors using PartialFunction chaining
Sometimes it can be useful to share common behavior among a few actors, or compose one actor's behavior from multiple smaller functions.
@ -1005,6 +1301,8 @@ traits and implementing the actor's `receive` as combination of these partial fu
Instead of inheritance the same pattern can be applied via composition - one would simply compose the receive method using partial functions from delegates.
@@@
## Initialization patterns
The rich lifecycle hooks of Actors provide a useful toolkit to implement various initialization patterns. During the
@ -1034,8 +1332,13 @@ this behavior, and ensure that there is only one call to `preStart()`.
One useful usage of this pattern is to disable creation of new `ActorRefs` for children during restarts. This can be
achieved by overriding `preRestart()`:
@@snip [InitializationDocSpec.scala]($code$/scala/docs/actor/InitializationDocSpec.scala) { #preStartInit }
Scala
: @@snip [InitializationDocSpec.scala]($code$/scala/docs/actor/InitializationDocSpec.scala) { #preStartInit }
Java
: @@snip [InitializationDocTest.java]($code$/java/jdocs/actor/InitializationDocTest.java) { #preStartInit }
Please note, that the child actors are *still restarted*, but no new `ActorRef` is created. One can recursively apply
the same principles for the children, ensuring that their `preStart()` method is called only at the creation of their
refs.
@ -1049,7 +1352,11 @@ for example in the presence of circular dependencies. In this case the actor sho
and use `become()` or a finite state-machine state transition to encode the initialized and uninitialized states
of the actor.
@@snip [InitializationDocSpec.scala]($code$/scala/docs/actor/InitializationDocSpec.scala) { #messageInit }
Scala
: @@snip [InitializationDocSpec.scala]($code$/scala/docs/actor/InitializationDocSpec.scala) { #messageInit }
Java
: @@snip [InitializationDocTest.java]($code$/java/jdocs/actor/InitializationDocTest.java) { #messageInit }
If the actor may receive messages before it has been initialized, a useful tool can be the `Stash` to save messages
until the initialization finishes, and replaying them after the actor became initialized.

View file

@ -0,0 +1,37 @@
# Java 8 and Scala Compatibility
Akka requires that you have [Java 8](http://www.oracle.com/technetwork/java/javase/downloads/index.html) or
later installed on your machine.
## Java 8 types
Starting with Akka 2.4.2 we have begun to introduce Java 8 types (most
prominently `java.util.concurrent.CompletionStage` and
`java.util.Optional`) where that was possible without breaking binary or
source compatibility. Where this was not possible (for example in the return
type of `ActorSystem.terminate()`) please refer to the
`scala-java8-compat` library that allows easy conversion between the Scala
and Java counterparts. The artifact can be included in Maven builds using:
```
<dependency>
<groupId>org.scala-lang.modules</groupId>
<artifactId>scala-java8-compat_2.11</artifactId>
<version>0.7.0</version>
</dependency>
```
We will only be able to seamlessly integrate all functional interfaces once
we can rely on Scala 2.12 to provide full interoperability—this will mean that
Scala users can directly implement Java Functional Interfaces using lambda syntax
as well as that Java users can directly implement Scala functions using lambda
syntax.
## Do not use -optimize Scala compiler flag
@@@ warning
Akka has not been compiled or tested with -optimize Scala compiler flag.
Strange behavior has been reported by users that have tried it.
@@@

View file

@ -310,6 +310,13 @@ class Ponger(pinger: ActorRef) extends Actor {
//#fiddle_code
//#immutable-message-definition
case class User(name: String)
// define the case class
case class Register(user: User)
//#immutable-message-definition
class ActorDocSpec extends AkkaSpec("""
akka.loglevel = INFO
akka.loggers = []
@ -381,6 +388,23 @@ class ActorDocSpec extends AkkaSpec("""
system.terminate()
}
"instantiates a case class" in {
//#immutable-message-instantiation
val user = User("Mike")
// create a new case class message
val message = Register(user)
//#immutable-message-instantiation
}
"use poison pill" in {
val victim = system.actorOf(Props[MyActor])
//#poison-pill
watch(victim)
victim ! PoisonPill
//#poison-pill
expectTerminated(victim)
}
"creating a Props config" in {
//#creating-props
import akka.actor.Props
@ -562,10 +586,12 @@ class ActorDocSpec extends AkkaSpec("""
}
}
//#watch
val a = system.actorOf(Props(classOf[WatchActor], this))
val victim = system.actorOf(Props(classOf[WatchActor], this))
implicit val sender = testActor
a ! "kill"
//#kill
victim ! "kill"
expectMsg("finished")
//#kill
}
}