Merge paradox/scala/howto.md and java/howto.md (#23159)

This commit is contained in:
Richard Imaoka 2017-06-14 22:27:46 +09:00 committed by Arnout Engelen
parent b05cd61ca2
commit 1d2748cad2
2 changed files with 63 additions and 85 deletions

View file

@ -1,83 +0,0 @@
# HowTo: Common Patterns
This section lists common actor patterns which have been found to be useful,
elegant or instructive. Anything is welcome, example topics being message
routing strategies, supervision patterns, restart handling, etc. As a special
bonus, additions to this section are marked with the contributors name, and it
would be nice if every Akka user who finds a recurring pattern in his or her
code could share it for the profit of all. Where applicable it might also make
sense to add to the `akka.pattern` package for creating an [OTP-like library](http://www.erlang.org/doc/man_index.html).
You might find some of the patterns described in the Scala chapter of
@ref:[HowTo: Common Patterns](howto.md) useful even though the example code is written in Scala.
## Scheduling Periodic Messages
This pattern describes how to schedule periodic messages to yourself in two different
ways.
The first way is to set up periodic message scheduling in the constructor of the actor,
and cancel that scheduled sending in `postStop` or else we might have multiple registered
message sends to the same actor.
@@@ note
With this approach the scheduled periodic message send will be restarted with the actor on restarts.
This also means that the time period that elapses between two tick messages during a restart may drift
off based on when you restart the scheduled message sends relative to the time that the last message was
sent, and how long the initial delay is. Worst case scenario is `interval` plus `initialDelay`.
@@@
@@snip [SchedulerPatternTest.java]($code$/java/jdocs/pattern/SchedulerPatternTest.java) { #schedule-constructor }
The second variant sets up an initial one shot message send in the `preStart` method
of the actor, and the then the actor when it receives this message sets up a new one shot
message send. You also have to override `postRestart` so we don't call `preStart`
and schedule the initial message send again.
@@@ note
With this approach we won't fill up the mailbox with tick messages if the actor is
under pressure, but only schedule a new tick message when we have seen the previous one.
@@@
@@snip [SchedulerPatternTest.java]($code$/java/jdocs/pattern/SchedulerPatternTest.java) { #schedule-receive }
## Single-Use Actor Trees with High-Level Error Reporting
*Contributed by: Rick Latrine*
A nice way to enter the actor world from java is the use of Patterns.ask().
This method starts a temporary actor to forward the message and collect the result from the actor to be "asked".
In case of errors within the asked actor the default supervision handling will take over.
The caller of Patterns.ask() will *not* be notified.
If that caller is interested in such an exception, they must make sure that the asked actor replies with Status.Failure(Throwable).
Behind the asked actor a complex actor hierarchy might be spawned to accomplish asynchronous work.
Then supervision is the established way to control error handling.
Unfortunately the asked actor must know about supervision and must catch the exceptions.
Such an actor is unlikely to be reused in a different actor hierarchy and contains crippled try/catch blocks.
This pattern provides a way to encapsulate supervision and error propagation to the temporary actor.
Finally the promise returned by Patterns.ask() is fulfilled as a failure, including the exception
(see also @ref:[Java 8 and Scala Compatibility](scala-compat.md) for Java compatibility).
Let's have a look at the example code:
@@snip [SupervisedAsk.java]($code$/java/jdocs/pattern/SupervisedAsk.java)
In the askOf method the SupervisorCreator is sent the user message.
The SupervisorCreator creates a SupervisorActor and forwards the message.
This prevents the actor system from overloading due to actor creations.
The SupervisorActor is responsible to create the user actor, forwards the message, handles actor termination and supervision.
Additionally the SupervisorActor stops the user actor if execution time expired.
In case of an exception the supervisor tells the temporary actor which exception was thrown.
Afterwards the actor hierarchy is stopped.
Finally we are able to execute an actor and receive the results or exceptions.
@@snip [SupervisedAskSpec.java]($code$/java/jdocs/pattern/SupervisedAskSpec.java)

View file

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

View file

@ -8,6 +8,15 @@ would be nice if every Akka user who finds a recurring pattern in his or her
code could share it for the profit of all. Where applicable it might also make code could share it for the profit of all. Where applicable it might also make
sense to add to the `akka.pattern` package for creating an [OTP-like library](http://www.erlang.org/doc/man_index.html). sense to add to the `akka.pattern` package for creating an [OTP-like library](http://www.erlang.org/doc/man_index.html).
@@@ div { .group-java }
You might find some of the patterns described in the Scala chapter of
this page useful even though the example code is written in Scala.
@@@
@@@ div { .group-scala }
## Throttling Messages ## Throttling Messages
Contributed by: Kaspar Fischer Contributed by: Kaspar Fischer
@ -109,6 +118,8 @@ This is where the Spider pattern comes in."
The pattern is described [Discovering Message Flows in Actor System with the Spider Pattern](http://letitcrash.com/post/30585282971/discovering-message-flows-in-actor-systems-with-the). The pattern is described [Discovering Message Flows in Actor System with the Spider Pattern](http://letitcrash.com/post/30585282971/discovering-message-flows-in-actor-systems-with-the).
@@@
## Scheduling Periodic Messages ## Scheduling Periodic Messages
This pattern describes how to schedule periodic messages to yourself in two different This pattern describes how to schedule periodic messages to yourself in two different
@ -127,7 +138,11 @@ sent, and how long the initial delay is. Worst case scenario is `interval` plus
@@@ @@@
@@snip [SchedulerPatternSpec.scala]($code$/scala/docs/pattern/SchedulerPatternSpec.scala) { #schedule-constructor } Scala
: @@snip [SchedulerPatternSpec.scala]($code$/scala/docs/pattern/SchedulerPatternSpec.scala) { #schedule-constructor }
Java
: @@snip [SchedulerPatternTest.java]($code$/java/jdocs/pattern/SchedulerPatternTest.java) { #schedule-constructor }
The second variant sets up an initial one shot message send in the `preStart` method The second variant sets up an initial one shot message send in the `preStart` method
of the actor, and the then the actor when it receives this message sets up a new one shot of the actor, and the then the actor when it receives this message sets up a new one shot
@ -141,4 +156,49 @@ under pressure, but only schedule a new tick message when we have seen the previ
@@@ @@@
@@snip [SchedulerPatternSpec.scala]($code$/scala/docs/pattern/SchedulerPatternSpec.scala) { #schedule-receive } Scala
: @@snip [SchedulerPatternSpec.scala]($code$/scala/docs/pattern/SchedulerPatternSpec.scala) { #schedule-receive }
Java
: @@snip [SchedulerPatternTest.java]($code$/java/jdocs/pattern/SchedulerPatternTest.java) { #schedule-receive }
@@@ div { .group-java }
## Single-Use Actor Trees with High-Level Error Reporting
*Contributed by: Rick Latrine*
A nice way to enter the actor world from java is the use of Patterns.ask().
This method starts a temporary actor to forward the message and collect the result from the actor to be "asked".
In case of errors within the asked actor the default supervision handling will take over.
The caller of Patterns.ask() will *not* be notified.
If that caller is interested in such an exception, they must make sure that the asked actor replies with Status.Failure(Throwable).
Behind the asked actor a complex actor hierarchy might be spawned to accomplish asynchronous work.
Then supervision is the established way to control error handling.
Unfortunately the asked actor must know about supervision and must catch the exceptions.
Such an actor is unlikely to be reused in a different actor hierarchy and contains crippled try/catch blocks.
This pattern provides a way to encapsulate supervision and error propagation to the temporary actor.
Finally the promise returned by Patterns.ask() is fulfilled as a failure, including the exception
(see also @ref:[Java 8 and Scala Compatibility](scala-compat.md) for Java compatibility).
Let's have a look at the example code:
@@snip [SupervisedAsk.java]($code$/java/jdocs/pattern/SupervisedAsk.java)
In the askOf method the SupervisorCreator is sent the user message.
The SupervisorCreator creates a SupervisorActor and forwards the message.
This prevents the actor system from overloading due to actor creations.
The SupervisorActor is responsible to create the user actor, forwards the message, handles actor termination and supervision.
Additionally the SupervisorActor stops the user actor if execution time expired.
In case of an exception the supervisor tells the temporary actor which exception was thrown.
Afterwards the actor hierarchy is stopped.
Finally we are able to execute an actor and receive the results or exceptions.
@@snip [SupervisedAskSpec.java]($code$/java/jdocs/pattern/SupervisedAskSpec.java)
@@@