Adds new extended backoff API and moves old deprecated API to separate file #26156
This commit is contained in:
parent
0abd8bab96
commit
6b77500392
4 changed files with 737 additions and 359 deletions
|
|
@ -5,5 +5,3 @@ ProblemFilters.exclude[DirectMissingMethodProblem]("akka.pattern.BackoffOnRestar
|
|||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.pattern.HandleBackoff.replyWhileStopped")
|
||||
ProblemFilters.exclude[DirectMissingMethodProblem]("akka.pattern.HandleBackoff.finalStopMessage")
|
||||
ProblemFilters.exclude[ReversedMissingMethodProblem]("akka.pattern.HandleBackoff.handleMessageToChild")
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("akka.pattern.Backoff.onFailure")
|
||||
ProblemFilters.exclude[IncompatibleResultTypeProblem]("akka.pattern.Backoff.onStop")
|
||||
610
akka-actor/src/main/scala/akka/pattern/Backoff.scala
Normal file
610
akka-actor/src/main/scala/akka/pattern/Backoff.scala
Normal file
|
|
@ -0,0 +1,610 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2019 Lightbend Inc. <https://www.lightbend.com>
|
||||
*/
|
||||
|
||||
package akka.pattern
|
||||
|
||||
import akka.actor.{ OneForOneStrategy, Props, SupervisorStrategy }
|
||||
import akka.annotation.DoNotInherit
|
||||
import akka.util.JavaDurationConverters._
|
||||
|
||||
import scala.concurrent.duration.{ Duration, FiniteDuration }
|
||||
|
||||
/**
|
||||
* @deprecated This API is superseded by the [[BackoffOptions]] object.
|
||||
*/
|
||||
@Deprecated
|
||||
@deprecated("Use new API from BackoffOptions object instead", since = "2.5.20")
|
||||
object Backoff {
|
||||
/**
|
||||
* Back-off options for creating a back-off supervisor actor that expects a child actor to restart on failure.
|
||||
*
|
||||
* This explicit supervisor behaves similarly to the normal implicit supervision where
|
||||
* if an actor throws an exception, the decider on the supervisor will decide when to
|
||||
* `Stop`, `Restart`, `Escalate`, `Resume` the child actor.
|
||||
*
|
||||
* When the `Restart` directive is specified, the supervisor will delay the restart
|
||||
* using an exponential back off strategy (bounded by minBackoff and maxBackoff).
|
||||
*
|
||||
* This supervisor is intended to be transparent to both the child actor and external actors.
|
||||
* Where external actors can send messages to the supervisor as if it was the child and the
|
||||
* messages will be forwarded. And when the child is `Terminated`, the supervisor is also
|
||||
* `Terminated`.
|
||||
* Transparent to the child means that the child does not have to be aware that it is being
|
||||
* supervised specifically by this actor. Just like it does
|
||||
* not need to know when it is being supervised by the usual implicit supervisors.
|
||||
* The only caveat is that the `ActorRef` of the child is not stable, so any user storing the
|
||||
* `sender()` `ActorRef` from the child response may eventually not be able to communicate with
|
||||
* the stored `ActorRef`. In general all messages to the child should be directed through this actor.
|
||||
*
|
||||
* An example of where this supervisor might be used is when you may have an actor that is
|
||||
* responsible for continuously polling on a server for some resource that sometimes may be down.
|
||||
* Instead of hammering the server continuously when the resource is unavailable, the actor will
|
||||
* be restarted with an exponentially increasing back off until the resource is available again.
|
||||
*
|
||||
* '''***
|
||||
* This supervisor should not be used with `Akka Persistence` child actors.
|
||||
* `Akka Persistence` actors shutdown unconditionally on `persistFailure()`s rather
|
||||
* than throw an exception on a failure like normal actors.
|
||||
* [[#onStop]] should be used instead for cases where the child actor
|
||||
* terminates itself as a failure signal instead of the normal behavior of throwing an exception.
|
||||
* ***'''
|
||||
* You can define another
|
||||
* supervision strategy by using `akka.pattern.BackoffOptions.withSupervisorStrategy` on [[akka.pattern.BackoffOptions]].
|
||||
*
|
||||
* @param childProps the [[akka.actor.Props]] of the child actor that
|
||||
* will be started and supervised
|
||||
* @param childName name of the child actor
|
||||
* @param minBackoff minimum (initial) duration until the child actor will
|
||||
* started again, if it is terminated
|
||||
* @param maxBackoff the exponential back-off is capped to this duration
|
||||
* @param randomFactor after calculation of the exponential back-off an additional
|
||||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
* @param maxNrOfRetries maximum number of attempts to restart the child actor.
|
||||
* The supervisor will terminate itself after the maxNoOfRetries is reached.
|
||||
* In order to restart infinitely pass in `-1`.
|
||||
*
|
||||
*/
|
||||
@deprecated("Use BackoffOptions.onFailure instead", "2.5.20")
|
||||
def onFailure(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: FiniteDuration,
|
||||
maxBackoff: FiniteDuration,
|
||||
randomFactor: Double,
|
||||
maxNrOfRetries: Int): BackoffOptions =
|
||||
BackoffOptionsImpl(RestartImpliesFailure, childProps, childName, minBackoff, maxBackoff, randomFactor).withMaxNrOfRetries(maxNrOfRetries)
|
||||
|
||||
/**
|
||||
* Back-off options for creating a back-off supervisor actor that expects a child actor to restart on failure.
|
||||
*
|
||||
* This explicit supervisor behaves similarly to the normal implicit supervision where
|
||||
* if an actor throws an exception, the decider on the supervisor will decide when to
|
||||
* `Stop`, `Restart`, `Escalate`, `Resume` the child actor.
|
||||
*
|
||||
* When the `Restart` directive is specified, the supervisor will delay the restart
|
||||
* using an exponential back off strategy (bounded by minBackoff and maxBackoff).
|
||||
*
|
||||
* This supervisor is intended to be transparent to both the child actor and external actors.
|
||||
* Where external actors can send messages to the supervisor as if it was the child and the
|
||||
* messages will be forwarded. And when the child is `Terminated`, the supervisor is also
|
||||
* `Terminated`.
|
||||
* Transparent to the child means that the child does not have to be aware that it is being
|
||||
* supervised specifically by this actor. Just like it does
|
||||
* not need to know when it is being supervised by the usual implicit supervisors.
|
||||
* The only caveat is that the `ActorRef` of the child is not stable, so any user storing the
|
||||
* `sender()` `ActorRef` from the child response may eventually not be able to communicate with
|
||||
* the stored `ActorRef`. In general all messages to the child should be directed through this actor.
|
||||
*
|
||||
* An example of where this supervisor might be used is when you may have an actor that is
|
||||
* responsible for continuously polling on a server for some resource that sometimes may be down.
|
||||
* Instead of hammering the server continuously when the resource is unavailable, the actor will
|
||||
* be restarted with an exponentially increasing back off until the resource is available again.
|
||||
*
|
||||
* '''***
|
||||
* This supervisor should not be used with `Akka Persistence` child actors.
|
||||
* `Akka Persistence` actors shutdown unconditionally on `persistFailure()`s rather
|
||||
* than throw an exception on a failure like normal actors.
|
||||
* [[#onStop]] should be used instead for cases where the child actor
|
||||
* terminates itself as a failure signal instead of the normal behavior of throwing an exception.
|
||||
* ***'''
|
||||
* You can define another
|
||||
* supervision strategy by using `akka.pattern.BackoffOptions.withSupervisorStrategy` on [[akka.pattern.BackoffOptions]].
|
||||
*
|
||||
* @param childProps the [[akka.actor.Props]] of the child actor that
|
||||
* will be started and supervised
|
||||
* @param childName name of the child actor
|
||||
* @param minBackoff minimum (initial) duration until the child actor will
|
||||
* started again, if it is terminated
|
||||
* @param maxBackoff the exponential back-off is capped to this duration
|
||||
* @param randomFactor after calculation of the exponential back-off an additional
|
||||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
*/
|
||||
@deprecated("Use BackoffOptions.onFailure instead", "2.5.20")
|
||||
def onFailure(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: FiniteDuration,
|
||||
maxBackoff: FiniteDuration,
|
||||
randomFactor: Double): BackoffOptions =
|
||||
BackoffOptionsImpl(RestartImpliesFailure, childProps, childName, minBackoff, maxBackoff, randomFactor)
|
||||
|
||||
/**
|
||||
* Java API: Back-off options for creating a back-off supervisor actor that expects a child actor to restart on failure.
|
||||
*
|
||||
* This explicit supervisor behaves similarly to the normal implicit supervision where
|
||||
* if an actor throws an exception, the decider on the supervisor will decide when to
|
||||
* `Stop`, `Restart`, `Escalate`, `Resume` the child actor.
|
||||
*
|
||||
* When the `Restart` directive is specified, the supervisor will delay the restart
|
||||
* using an exponential back off strategy (bounded by minBackoff and maxBackoff).
|
||||
*
|
||||
* This supervisor is intended to be transparent to both the child actor and external actors.
|
||||
* Where external actors can send messages to the supervisor as if it was the child and the
|
||||
* messages will be forwarded. And when the child is `Terminated`, the supervisor is also
|
||||
* `Terminated`.
|
||||
* Transparent to the child means that the child does not have to be aware that it is being
|
||||
* supervised specifically by this actor. Just like it does
|
||||
* not need to know when it is being supervised by the usual implicit supervisors.
|
||||
* The only caveat is that the `ActorRef` of the child is not stable, so any user storing the
|
||||
* `sender()` `ActorRef` from the child response may eventually not be able to communicate with
|
||||
* the stored `ActorRef`. In general all messages to the child should be directed through this actor.
|
||||
*
|
||||
* An example of where this supervisor might be used is when you may have an actor that is
|
||||
* responsible for continuously polling on a server for some resource that sometimes may be down.
|
||||
* Instead of hammering the server continuously when the resource is unavailable, the actor will
|
||||
* be restarted with an exponentially increasing back off until the resource is available again.
|
||||
*
|
||||
* '''***
|
||||
* This supervisor should not be used with `Akka Persistence` child actors.
|
||||
* `Akka Persistence` actors shutdown unconditionally on `persistFailure()`s rather
|
||||
* than throw an exception on a failure like normal actors.
|
||||
* [[#onStop]] should be used instead for cases where the child actor
|
||||
* terminates itself as a failure signal instead of the normal behavior of throwing an exception.
|
||||
* ***'''
|
||||
* You can define another
|
||||
* supervision strategy by using `akka.pattern.BackoffOptions.withSupervisorStrategy` on [[akka.pattern.BackoffOptions]].
|
||||
*
|
||||
* @param childProps the [[akka.actor.Props]] of the child actor that
|
||||
* will be started and supervised
|
||||
* @param childName name of the child actor
|
||||
* @param minBackoff minimum (initial) duration until the child actor will
|
||||
* started again, if it is terminated
|
||||
* @param maxBackoff the exponential back-off is capped to this duration
|
||||
* @param randomFactor after calculation of the exponential back-off an additional
|
||||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
* @param maxNrOfRetries maximum number of attempts to restart the child actor.
|
||||
* The supervisor will terminate itself after the maxNoOfRetries is reached.
|
||||
* In order to restart infinitely pass in `-1`.
|
||||
*/
|
||||
@Deprecated
|
||||
@deprecated("Use BackoffOptions.onFailure instead", "2.5.20")
|
||||
def onFailure(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: java.time.Duration,
|
||||
maxBackoff: java.time.Duration,
|
||||
randomFactor: Double,
|
||||
maxNrOfRetries: Int): BackoffOptions =
|
||||
onFailure(childProps, childName, minBackoff.asScala, maxBackoff.asScala, randomFactor, maxNrOfRetries)
|
||||
|
||||
/**
|
||||
* Java API: Back-off options for creating a back-off supervisor actor that expects a child actor to restart on failure.
|
||||
*
|
||||
* This explicit supervisor behaves similarly to the normal implicit supervision where
|
||||
* if an actor throws an exception, the decider on the supervisor will decide when to
|
||||
* `Stop`, `Restart`, `Escalate`, `Resume` the child actor.
|
||||
*
|
||||
* When the `Restart` directive is specified, the supervisor will delay the restart
|
||||
* using an exponential back off strategy (bounded by minBackoff and maxBackoff).
|
||||
*
|
||||
* This supervisor is intended to be transparent to both the child actor and external actors.
|
||||
* Where external actors can send messages to the supervisor as if it was the child and the
|
||||
* messages will be forwarded. And when the child is `Terminated`, the supervisor is also
|
||||
* `Terminated`.
|
||||
* Transparent to the child means that the child does not have to be aware that it is being
|
||||
* supervised specifically by this actor. Just like it does
|
||||
* not need to know when it is being supervised by the usual implicit supervisors.
|
||||
* The only caveat is that the `ActorRef` of the child is not stable, so any user storing the
|
||||
* `sender()` `ActorRef` from the child response may eventually not be able to communicate with
|
||||
* the stored `ActorRef`. In general all messages to the child should be directed through this actor.
|
||||
*
|
||||
* An example of where this supervisor might be used is when you may have an actor that is
|
||||
* responsible for continuously polling on a server for some resource that sometimes may be down.
|
||||
* Instead of hammering the server continuously when the resource is unavailable, the actor will
|
||||
* be restarted with an exponentially increasing back off until the resource is available again.
|
||||
*
|
||||
* '''***
|
||||
* This supervisor should not be used with `Akka Persistence` child actors.
|
||||
* `Akka Persistence` actors shutdown unconditionally on `persistFailure()`s rather
|
||||
* than throw an exception on a failure like normal actors.
|
||||
* [[#onStop]] should be used instead for cases where the child actor
|
||||
* terminates itself as a failure signal instead of the normal behavior of throwing an exception.
|
||||
* ***'''
|
||||
* You can define another
|
||||
* supervision strategy by using `akka.pattern.BackoffOptions.withSupervisorStrategy` on [[akka.pattern.BackoffOptions]].
|
||||
*
|
||||
* @param childProps the [[akka.actor.Props]] of the child actor that
|
||||
* will be started and supervised
|
||||
* @param childName name of the child actor
|
||||
* @param minBackoff minimum (initial) duration until the child actor will
|
||||
* started again, if it is terminated
|
||||
* @param maxBackoff the exponential back-off is capped to this duration
|
||||
* @param randomFactor after calculation of the exponential back-off an additional
|
||||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
*/
|
||||
@Deprecated
|
||||
@deprecated("Use the overloaded one which accepts maxNrOfRetries instead.", "2.5.17")
|
||||
def onFailure(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: java.time.Duration,
|
||||
maxBackoff: java.time.Duration,
|
||||
randomFactor: Double): BackoffOptions =
|
||||
onFailure(childProps, childName, minBackoff.asScala, maxBackoff.asScala, randomFactor, -1)
|
||||
|
||||
/**
|
||||
* Back-off options for creating a back-off supervisor actor that expects a child actor to stop on failure.
|
||||
*
|
||||
* This actor can be used to supervise a child actor and start it again
|
||||
* after a back-off duration if the child actor is stopped.
|
||||
*
|
||||
* This is useful in situations where the re-start of the child actor should be
|
||||
* delayed e.g. in order to give an external resource time to recover before the
|
||||
* child actor tries contacting it again (after being restarted).
|
||||
*
|
||||
* Specifically this pattern is useful for persistent actors,
|
||||
* which are stopped in case of persistence failures.
|
||||
* Just restarting them immediately would probably fail again (since the data
|
||||
* store is probably unavailable). It is better to try again after a delay.
|
||||
*
|
||||
* It supports exponential back-off between the given `minBackoff` and
|
||||
* `maxBackoff` durations. For example, if `minBackoff` is 3 seconds and
|
||||
* `maxBackoff` 30 seconds the start attempts will be delayed with
|
||||
* 3, 6, 12, 24, 30, 30 seconds. The exponential back-off counter is reset
|
||||
* if the actor is not terminated within the `minBackoff` duration.
|
||||
*
|
||||
* In addition to the calculated exponential back-off an additional
|
||||
* random delay based the given `randomFactor` is added, e.g. 0.2 adds up to 20%
|
||||
* delay. The reason for adding a random delay is to avoid that all failing
|
||||
* actors hit the backend resource at the same time.
|
||||
*
|
||||
* You can retrieve the current child `ActorRef` by sending `BackoffSupervisor.GetCurrentChild`
|
||||
* message to this actor and it will reply with [[akka.pattern.BackoffSupervisor.CurrentChild]]
|
||||
* containing the `ActorRef` of the current child, if any.
|
||||
*
|
||||
* The `BackoffSupervisor`delegates all messages from the child to the parent of the
|
||||
* `BackoffSupervisor`, with the supervisor as sender.
|
||||
*
|
||||
* The `BackoffSupervisor` forwards all other messages to the child, if it is currently running.
|
||||
*
|
||||
* The child can stop itself and send a [[akka.actor.PoisonPill]] to the parent supervisor
|
||||
* if it wants to do an intentional stop.
|
||||
*
|
||||
* Exceptions in the child are handled with the default supervisionStrategy, which can be changed by using
|
||||
* [[BackoffOptions#withSupervisorStrategy]] or [[BackoffOptions#withDefaultStoppingStrategy]]. A
|
||||
* `Restart` will perform a normal immediate restart of the child. A `Stop` will
|
||||
* stop the child, but it will be started again after the back-off duration.
|
||||
*
|
||||
* @param childProps the [[akka.actor.Props]] of the child actor that
|
||||
* will be started and supervised
|
||||
* @param childName name of the child actor
|
||||
* @param minBackoff minimum (initial) duration until the child actor will
|
||||
* started again, if it is terminated
|
||||
* @param maxBackoff the exponential back-off is capped to this duration
|
||||
* @param randomFactor after calculation of the exponential back-off an additional
|
||||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
* @param maxNrOfRetries maximum number of attempts to restart the child actor.
|
||||
* The supervisor will terminate itself after the maxNoOfRetries is reached.
|
||||
* In order to restart infinitely pass in `-1`.
|
||||
*/
|
||||
@deprecated("Use BackoffOptions.onStop instead", "2.5.20")
|
||||
def onStop(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: FiniteDuration,
|
||||
maxBackoff: FiniteDuration,
|
||||
randomFactor: Double,
|
||||
maxNrOfRetries: Int): BackoffOptions =
|
||||
BackoffOptionsImpl(StopImpliesFailure, childProps, childName, minBackoff, maxBackoff, randomFactor).withMaxNrOfRetries(maxNrOfRetries)
|
||||
|
||||
/**
|
||||
* Back-off options for creating a back-off supervisor actor that expects a child actor to stop on failure.
|
||||
*
|
||||
* This actor can be used to supervise a child actor and start it again
|
||||
* after a back-off duration if the child actor is stopped.
|
||||
*
|
||||
* This is useful in situations where the re-start of the child actor should be
|
||||
* delayed e.g. in order to give an external resource time to recover before the
|
||||
* child actor tries contacting it again (after being restarted).
|
||||
*
|
||||
* Specifically this pattern is useful for persistent actors,
|
||||
* which are stopped in case of persistence failures.
|
||||
* Just restarting them immediately would probably fail again (since the data
|
||||
* store is probably unavailable). It is better to try again after a delay.
|
||||
*
|
||||
* It supports exponential back-off between the given `minBackoff` and
|
||||
* `maxBackoff` durations. For example, if `minBackoff` is 3 seconds and
|
||||
* `maxBackoff` 30 seconds the start attempts will be delayed with
|
||||
* 3, 6, 12, 24, 30, 30 seconds. The exponential back-off counter is reset
|
||||
* if the actor is not terminated within the `minBackoff` duration.
|
||||
*
|
||||
* In addition to the calculated exponential back-off an additional
|
||||
* random delay based the given `randomFactor` is added, e.g. 0.2 adds up to 20%
|
||||
* delay. The reason for adding a random delay is to avoid that all failing
|
||||
* actors hit the backend resource at the same time.
|
||||
*
|
||||
* You can retrieve the current child `ActorRef` by sending `BackoffSupervisor.GetCurrentChild`
|
||||
* message to this actor and it will reply with [[akka.pattern.BackoffSupervisor.CurrentChild]]
|
||||
* containing the `ActorRef` of the current child, if any.
|
||||
*
|
||||
* The `BackoffSupervisor`delegates all messages from the child to the parent of the
|
||||
* `BackoffSupervisor`, with the supervisor as sender.
|
||||
*
|
||||
* The `BackoffSupervisor` forwards all other messages to the child, if it is currently running.
|
||||
*
|
||||
* The child can stop itself and send a [[akka.actor.PoisonPill]] to the parent supervisor
|
||||
* if it wants to do an intentional stop.
|
||||
*
|
||||
* Exceptions in the child are handled with the default supervisionStrategy, which can be changed by using
|
||||
* [[BackoffOptions#withSupervisorStrategy]] or [[BackoffOptions#withDefaultStoppingStrategy]]. A
|
||||
* `Restart` will perform a normal immediate restart of the child. A `Stop` will
|
||||
* stop the child, but it will be started again after the back-off duration.
|
||||
*
|
||||
* @param childProps the [[akka.actor.Props]] of the child actor that
|
||||
* will be started and supervised
|
||||
* @param childName name of the child actor
|
||||
* @param minBackoff minimum (initial) duration until the child actor will
|
||||
* started again, if it is terminated
|
||||
* @param maxBackoff the exponential back-off is capped to this duration
|
||||
* @param randomFactor after calculation of the exponential back-off an additional
|
||||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
*/
|
||||
@deprecated("Use BackoffOptions.onStop instead", "2.5.20")
|
||||
def onStop(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: FiniteDuration,
|
||||
maxBackoff: FiniteDuration,
|
||||
randomFactor: Double): BackoffOptions =
|
||||
BackoffOptionsImpl(StopImpliesFailure, childProps, childName, minBackoff, maxBackoff, randomFactor)
|
||||
|
||||
/**
|
||||
* Java API: Back-off options for creating a back-off supervisor actor that expects a child actor to stop on failure.
|
||||
*
|
||||
* This actor can be used to supervise a child actor and start it again
|
||||
* after a back-off duration if the child actor is stopped.
|
||||
*
|
||||
* This is useful in situations where the re-start of the child actor should be
|
||||
* delayed e.g. in order to give an external resource time to recover before the
|
||||
* child actor tries contacting it again (after being restarted).
|
||||
*
|
||||
* Specifically this pattern is useful for persistent actors,
|
||||
* which are stopped in case of persistence failures.
|
||||
* Just restarting them immediately would probably fail again (since the data
|
||||
* store is probably unavailable). It is better to try again after a delay.
|
||||
*
|
||||
* It supports exponential back-off between the given `minBackoff` and
|
||||
* `maxBackoff` durations. For example, if `minBackoff` is 3 seconds and
|
||||
* `maxBackoff` 30 seconds the start attempts will be delayed with
|
||||
* 3, 6, 12, 24, 30, 30 seconds. The exponential back-off counter is reset
|
||||
* if the actor is not terminated within the `minBackoff` duration.
|
||||
*
|
||||
* In addition to the calculated exponential back-off an additional
|
||||
* random delay based the given `randomFactor` is added, e.g. 0.2 adds up to 20%
|
||||
* delay. The reason for adding a random delay is to avoid that all failing
|
||||
* actors hit the backend resource at the same time.
|
||||
*
|
||||
* You can retrieve the current child `ActorRef` by sending `BackoffSupervisor.GetCurrentChild`
|
||||
* message to this actor and it will reply with [[akka.pattern.BackoffSupervisor.CurrentChild]]
|
||||
* containing the `ActorRef` of the current child, if any.
|
||||
*
|
||||
* The `BackoffSupervisor`delegates all messages from the child to the parent of the
|
||||
* `BackoffSupervisor`, with the supervisor as sender.
|
||||
*
|
||||
* The `BackoffSupervisor` forwards all other messages to the child, if it is currently running.
|
||||
*
|
||||
* The child can stop itself and send a [[akka.actor.PoisonPill]] to the parent supervisor
|
||||
* if it wants to do an intentional stop.
|
||||
*
|
||||
* Exceptions in the child are handled with the default supervisionStrategy, which can be changed by using
|
||||
* [[BackoffOptions#withSupervisorStrategy]] or [[BackoffOptions#withDefaultStoppingStrategy]]. A
|
||||
* `Restart` will perform a normal immediate restart of the child. A `Stop` will
|
||||
* stop the child, but it will be started again after the back-off duration.
|
||||
*
|
||||
* @param childProps the [[akka.actor.Props]] of the child actor that
|
||||
* will be started and supervised
|
||||
* @param childName name of the child actor
|
||||
* @param minBackoff minimum (initial) duration until the child actor will
|
||||
* started again, if it is terminated
|
||||
* @param maxBackoff the exponential back-off is capped to this duration
|
||||
* @param randomFactor after calculation of the exponential back-off an additional
|
||||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
* @param maxNrOfRetries maximum number of attempts to restart the child actor.
|
||||
* The supervisor will terminate itself after the maxNoOfRetries is reached.
|
||||
* In order to restart infinitely pass in `-1`.
|
||||
*/
|
||||
@Deprecated
|
||||
@deprecated("Use BackoffOptions.onStop instead", "2.5.20")
|
||||
def onStop(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: java.time.Duration,
|
||||
maxBackoff: java.time.Duration,
|
||||
randomFactor: Double,
|
||||
maxNrOfRetries: Int): BackoffOptions =
|
||||
onStop(childProps, childName, minBackoff.asScala, maxBackoff.asScala, randomFactor, maxNrOfRetries)
|
||||
|
||||
/**
|
||||
* Java API: Back-off options for creating a back-off supervisor actor that expects a child actor to stop on failure.
|
||||
*
|
||||
* This actor can be used to supervise a child actor and start it again
|
||||
* after a back-off duration if the child actor is stopped.
|
||||
*
|
||||
* This is useful in situations where the re-start of the child actor should be
|
||||
* delayed e.g. in order to give an external resource time to recover before the
|
||||
* child actor tries contacting it again (after being restarted).
|
||||
*
|
||||
* Specifically this pattern is useful for persistent actors,
|
||||
* which are stopped in case of persistence failures.
|
||||
* Just restarting them immediately would probably fail again (since the data
|
||||
* store is probably unavailable). It is better to try again after a delay.
|
||||
*
|
||||
* It supports exponential back-off between the given `minBackoff` and
|
||||
* `maxBackoff` durations. For example, if `minBackoff` is 3 seconds and
|
||||
* `maxBackoff` 30 seconds the start attempts will be delayed with
|
||||
* 3, 6, 12, 24, 30, 30 seconds. The exponential back-off counter is reset
|
||||
* if the actor is not terminated within the `minBackoff` duration.
|
||||
*
|
||||
* In addition to the calculated exponential back-off an additional
|
||||
* random delay based the given `randomFactor` is added, e.g. 0.2 adds up to 20%
|
||||
* delay. The reason for adding a random delay is to avoid that all failing
|
||||
* actors hit the backend resource at the same time.
|
||||
*
|
||||
* You can retrieve the current child `ActorRef` by sending `BackoffSupervisor.GetCurrentChild`
|
||||
* message to this actor and it will reply with [[akka.pattern.BackoffSupervisor.CurrentChild]]
|
||||
* containing the `ActorRef` of the current child, if any.
|
||||
*
|
||||
* The `BackoffSupervisor`delegates all messages from the child to the parent of the
|
||||
* `BackoffSupervisor`, with the supervisor as sender.
|
||||
*
|
||||
* The `BackoffSupervisor` forwards all other messages to the child, if it is currently running.
|
||||
*
|
||||
* The child can stop itself and send a [[akka.actor.PoisonPill]] to the parent supervisor
|
||||
* if it wants to do an intentional stop.
|
||||
*
|
||||
* Exceptions in the child are handled with the default supervisionStrategy, which can be changed by using
|
||||
* [[BackoffOptions#withSupervisorStrategy]] or [[BackoffOptions#withDefaultStoppingStrategy]]. A
|
||||
* `Restart` will perform a normal immediate restart of the child. A `Stop` will
|
||||
* stop the child, but it will be started again after the back-off duration.
|
||||
*
|
||||
* @param childProps the [[akka.actor.Props]] of the child actor that
|
||||
* will be started and supervised
|
||||
* @param childName name of the child actor
|
||||
* @param minBackoff minimum (initial) duration until the child actor will
|
||||
* started again, if it is terminated
|
||||
* @param maxBackoff the exponential back-off is capped to this duration
|
||||
* @param randomFactor after calculation of the exponential back-off an additional
|
||||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
*/
|
||||
@Deprecated
|
||||
@deprecated("Use the overloaded one which accepts maxNrOfRetries instead.", "2.5.17")
|
||||
def onStop(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: java.time.Duration,
|
||||
maxBackoff: java.time.Duration,
|
||||
randomFactor: Double): BackoffOptions =
|
||||
onStop(childProps, childName, minBackoff.asScala, maxBackoff.asScala, randomFactor, -1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a back-off supervisor actor. Start with `Backoff.onStop` or `Backoff.onFailure`.
|
||||
* BackoffOptions is immutable, so be sure to chain methods like:
|
||||
* {{{
|
||||
* val options = Backoff.onFailure(childProps, childName, minBackoff, maxBackoff, randomFactor)
|
||||
* .withManualReset
|
||||
* context.actorOf(BackoffSupervisor.props(options), name)
|
||||
* }}}
|
||||
*/
|
||||
@DoNotInherit
|
||||
@Deprecated
|
||||
@deprecated("Use new API from BackoffOptions object instead", since = "2.5.20")
|
||||
trait BackoffOptions {
|
||||
|
||||
/**
|
||||
* @see [[ExtendedBackoffOptions.withAutoReset()]]
|
||||
*/
|
||||
def withAutoReset(resetBackoff: FiniteDuration): BackoffOptions
|
||||
|
||||
/**
|
||||
* @see [[ExtendedBackoffOptions.withManualReset()]]
|
||||
*/
|
||||
def withManualReset: BackoffOptions
|
||||
|
||||
/**
|
||||
* @see [[ExtendedBackoffOptions.withSupervisorStrategy()]]
|
||||
*/
|
||||
def withSupervisorStrategy(supervisorStrategy: OneForOneStrategy): BackoffOptions
|
||||
|
||||
/**
|
||||
* @see [[ExtendedBackoffOptions.withDefaultStoppingStrategy()]]
|
||||
*/
|
||||
def withDefaultStoppingStrategy: BackoffOptions
|
||||
|
||||
/**
|
||||
* @see [[ExtendedBackoffOptions.withMaxNrOfRetries()]]
|
||||
*/
|
||||
def withMaxNrOfRetries(maxNrOfRetries: Int): BackoffOptions
|
||||
|
||||
/**
|
||||
* @see [[ExtendedBackoffOptions.withReplyWhileStopped()]]
|
||||
*/
|
||||
def withReplyWhileStopped(replyWhileStopped: Any): BackoffOptions
|
||||
|
||||
/**
|
||||
* @see [[BackoffOnStopOptions.withFinalStopMessage()]]
|
||||
*/
|
||||
def withFinalStopMessage(isFinalStopMessage: Any ⇒ Boolean): BackoffOptions
|
||||
|
||||
/**
|
||||
* Returns the props to create the back-off supervisor.
|
||||
*/
|
||||
private[akka] def props: Props
|
||||
}
|
||||
|
||||
private final case class BackoffOptionsImpl(
|
||||
backoffType: BackoffType = RestartImpliesFailure,
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: FiniteDuration,
|
||||
maxBackoff: FiniteDuration,
|
||||
randomFactor: Double,
|
||||
reset: Option[BackoffReset] = None,
|
||||
supervisorStrategy: OneForOneStrategy = OneForOneStrategy()(SupervisorStrategy.defaultStrategy.decider),
|
||||
replyWhileStopped: Option[Any] = None,
|
||||
finalStopMessage: Option[Any ⇒ Boolean] = None
|
||||
) extends akka.pattern.BackoffOptions {
|
||||
|
||||
val backoffReset = reset.getOrElse(AutoReset(minBackoff))
|
||||
|
||||
def withAutoReset(resetBackoff: FiniteDuration) = copy(reset = Some(AutoReset(resetBackoff)))
|
||||
def withManualReset = copy(reset = Some(ManualReset))
|
||||
def withSupervisorStrategy(supervisorStrategy: OneForOneStrategy) = copy(supervisorStrategy = supervisorStrategy)
|
||||
def withDefaultStoppingStrategy = copy(supervisorStrategy = OneForOneStrategy(supervisorStrategy.maxNrOfRetries)(SupervisorStrategy.stoppingStrategy.decider))
|
||||
def withReplyWhileStopped(replyWhileStopped: Any) = copy(replyWhileStopped = Some(replyWhileStopped))
|
||||
def withMaxNrOfRetries(maxNrOfRetries: Int) = copy(supervisorStrategy = supervisorStrategy.withMaxNrOfRetries(maxNrOfRetries))
|
||||
def withFinalStopMessage(action: Any ⇒ Boolean) = copy(finalStopMessage = Some(action))
|
||||
|
||||
def props = {
|
||||
require(minBackoff > Duration.Zero, "minBackoff must be > 0")
|
||||
require(maxBackoff >= minBackoff, "maxBackoff must be >= minBackoff")
|
||||
require(0.0 <= randomFactor && randomFactor <= 1.0, "randomFactor must be between 0.0 and 1.0")
|
||||
backoffReset match {
|
||||
case AutoReset(resetBackoff) ⇒
|
||||
require(minBackoff <= resetBackoff && resetBackoff <= maxBackoff)
|
||||
case _ ⇒ // ignore
|
||||
}
|
||||
|
||||
backoffType match {
|
||||
//onFailure method in companion object
|
||||
case RestartImpliesFailure ⇒
|
||||
Props(new BackoffOnRestartSupervisor(childProps, childName, minBackoff, maxBackoff, backoffReset, randomFactor, supervisorStrategy, replyWhileStopped))
|
||||
//onStop method in companion object
|
||||
case StopImpliesFailure ⇒
|
||||
Props(new BackoffOnStopSupervisor(childProps, childName, minBackoff, maxBackoff, backoffReset, randomFactor, supervisorStrategy, replyWhileStopped, finalStopMessage))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed trait BackoffType
|
||||
private final case object StopImpliesFailure extends BackoffType
|
||||
private final case object RestartImpliesFailure extends BackoffType
|
||||
|
|
@ -4,29 +4,16 @@
|
|||
|
||||
package akka.pattern
|
||||
|
||||
import scala.concurrent.duration.{ Duration, FiniteDuration }
|
||||
import akka.util.JavaDurationConverters._
|
||||
import akka.actor.{ OneForOneStrategy, Props, SupervisorStrategy }
|
||||
import akka.annotation.DoNotInherit
|
||||
import akka.util.JavaDurationConverters._
|
||||
|
||||
import scala.concurrent.duration.{ Duration, FiniteDuration }
|
||||
|
||||
/**
|
||||
* Builds back-off options for creating a back-off supervisor.
|
||||
* You can pass `BackoffOptions` to `akka.pattern.BackoffSupervisor.props`.
|
||||
* An example of creating back-off options:
|
||||
* {{{
|
||||
* Backoff.onFailure(childProps, childName, minBackoff, maxBackoff, randomFactor)
|
||||
* .withManualReset
|
||||
* .withSupervisorStrategy(
|
||||
* OneforOneStrategy(){
|
||||
* case e: GivingUpException => Stop
|
||||
* case e: RetryableException => Restart
|
||||
* }
|
||||
* )
|
||||
* .withReplyWhileStopped(TheSystemIsDown)
|
||||
*
|
||||
* }}}
|
||||
* Backoff options allow to specify a number of properties for backoff supervisors.
|
||||
*/
|
||||
object Backoff {
|
||||
object BackoffOpts {
|
||||
/**
|
||||
* Back-off options for creating a back-off supervisor actor that expects a child actor to restart on failure.
|
||||
*
|
||||
|
|
@ -61,66 +48,7 @@ object Backoff {
|
|||
* terminates itself as a failure signal instead of the normal behavior of throwing an exception.
|
||||
* ***'''
|
||||
* You can define another
|
||||
* supervision strategy by using `akka.pattern.BackoffOptions.withSupervisorStrategy` on [[akka.pattern.BackoffOptions]].
|
||||
*
|
||||
* @param childProps the [[akka.actor.Props]] of the child actor that
|
||||
* will be started and supervised
|
||||
* @param childName name of the child actor
|
||||
* @param minBackoff minimum (initial) duration until the child actor will
|
||||
* started again, if it is terminated
|
||||
* @param maxBackoff the exponential back-off is capped to this duration
|
||||
* @param randomFactor after calculation of the exponential back-off an additional
|
||||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
* @param maxNrOfRetries maximum number of attempts to restart the child actor.
|
||||
* The supervisor will terminate itself after the maxNoOfRetries is reached.
|
||||
* In order to restart infinitely pass in `-1`.
|
||||
*
|
||||
*/
|
||||
def onFailure(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: FiniteDuration,
|
||||
maxBackoff: FiniteDuration,
|
||||
randomFactor: Double,
|
||||
maxNrOfRetries: Int): BackoffOnFailureOptions =
|
||||
BackoffOptionsImpl(RestartImpliesFailure, childProps, childName, minBackoff, maxBackoff, randomFactor).withMaxNrOfRetries(maxNrOfRetries)
|
||||
|
||||
/**
|
||||
* Back-off options for creating a back-off supervisor actor that expects a child actor to restart on failure.
|
||||
*
|
||||
* This explicit supervisor behaves similarly to the normal implicit supervision where
|
||||
* if an actor throws an exception, the decider on the supervisor will decide when to
|
||||
* `Stop`, `Restart`, `Escalate`, `Resume` the child actor.
|
||||
*
|
||||
* When the `Restart` directive is specified, the supervisor will delay the restart
|
||||
* using an exponential back off strategy (bounded by minBackoff and maxBackoff).
|
||||
*
|
||||
* This supervisor is intended to be transparent to both the child actor and external actors.
|
||||
* Where external actors can send messages to the supervisor as if it was the child and the
|
||||
* messages will be forwarded. And when the child is `Terminated`, the supervisor is also
|
||||
* `Terminated`.
|
||||
* Transparent to the child means that the child does not have to be aware that it is being
|
||||
* supervised specifically by this actor. Just like it does
|
||||
* not need to know when it is being supervised by the usual implicit supervisors.
|
||||
* The only caveat is that the `ActorRef` of the child is not stable, so any user storing the
|
||||
* `sender()` `ActorRef` from the child response may eventually not be able to communicate with
|
||||
* the stored `ActorRef`. In general all messages to the child should be directed through this actor.
|
||||
*
|
||||
* An example of where this supervisor might be used is when you may have an actor that is
|
||||
* responsible for continuously polling on a server for some resource that sometimes may be down.
|
||||
* Instead of hammering the server continuously when the resource is unavailable, the actor will
|
||||
* be restarted with an exponentially increasing back off until the resource is available again.
|
||||
*
|
||||
* '''***
|
||||
* This supervisor should not be used with `Akka Persistence` child actors.
|
||||
* `Akka Persistence` actors shutdown unconditionally on `persistFailure()`s rather
|
||||
* than throw an exception on a failure like normal actors.
|
||||
* [[#onStop]] should be used instead for cases where the child actor
|
||||
* terminates itself as a failure signal instead of the normal behavior of throwing an exception.
|
||||
* ***'''
|
||||
* You can define another
|
||||
* supervision strategy by using `akka.pattern.BackoffOptions.withSupervisorStrategy` on [[akka.pattern.BackoffOptions]].
|
||||
* supervision strategy by using `akka.pattern.BackoffOptions.withSupervisorStrategy` on [[akka.pattern.BackoffOnFailureOptions]].
|
||||
*
|
||||
* @param childProps the [[akka.actor.Props]] of the child actor that
|
||||
* will be started and supervised
|
||||
|
|
@ -138,7 +66,7 @@ object Backoff {
|
|||
minBackoff: FiniteDuration,
|
||||
maxBackoff: FiniteDuration,
|
||||
randomFactor: Double): BackoffOnFailureOptions =
|
||||
BackoffOptionsImpl(RestartImpliesFailure, childProps, childName, minBackoff, maxBackoff, randomFactor)
|
||||
BackoffOnFailureOptionsImpl(childProps, childName, minBackoff, maxBackoff, randomFactor)
|
||||
|
||||
/**
|
||||
* Java API: Back-off options for creating a back-off supervisor actor that expects a child actor to restart on failure.
|
||||
|
|
@ -174,65 +102,7 @@ object Backoff {
|
|||
* terminates itself as a failure signal instead of the normal behavior of throwing an exception.
|
||||
* ***'''
|
||||
* You can define another
|
||||
* supervision strategy by using `akka.pattern.BackoffOptions.withSupervisorStrategy` on [[akka.pattern.BackoffOptions]].
|
||||
*
|
||||
* @param childProps the [[akka.actor.Props]] of the child actor that
|
||||
* will be started and supervised
|
||||
* @param childName name of the child actor
|
||||
* @param minBackoff minimum (initial) duration until the child actor will
|
||||
* started again, if it is terminated
|
||||
* @param maxBackoff the exponential back-off is capped to this duration
|
||||
* @param randomFactor after calculation of the exponential back-off an additional
|
||||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
* @param maxNrOfRetries maximum number of attempts to restart the child actor.
|
||||
* The supervisor will terminate itself after the maxNoOfRetries is reached.
|
||||
* In order to restart infinitely pass in `-1`.
|
||||
*/
|
||||
def onFailure(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: java.time.Duration,
|
||||
maxBackoff: java.time.Duration,
|
||||
randomFactor: Double,
|
||||
maxNrOfRetries: Int): BackoffOnFailureOptions =
|
||||
onFailure(childProps, childName, minBackoff.asScala, maxBackoff.asScala, randomFactor, maxNrOfRetries)
|
||||
|
||||
/**
|
||||
* Java API: Back-off options for creating a back-off supervisor actor that expects a child actor to restart on failure.
|
||||
*
|
||||
* This explicit supervisor behaves similarly to the normal implicit supervision where
|
||||
* if an actor throws an exception, the decider on the supervisor will decide when to
|
||||
* `Stop`, `Restart`, `Escalate`, `Resume` the child actor.
|
||||
*
|
||||
* When the `Restart` directive is specified, the supervisor will delay the restart
|
||||
* using an exponential back off strategy (bounded by minBackoff and maxBackoff).
|
||||
*
|
||||
* This supervisor is intended to be transparent to both the child actor and external actors.
|
||||
* Where external actors can send messages to the supervisor as if it was the child and the
|
||||
* messages will be forwarded. And when the child is `Terminated`, the supervisor is also
|
||||
* `Terminated`.
|
||||
* Transparent to the child means that the child does not have to be aware that it is being
|
||||
* supervised specifically by this actor. Just like it does
|
||||
* not need to know when it is being supervised by the usual implicit supervisors.
|
||||
* The only caveat is that the `ActorRef` of the child is not stable, so any user storing the
|
||||
* `sender()` `ActorRef` from the child response may eventually not be able to communicate with
|
||||
* the stored `ActorRef`. In general all messages to the child should be directed through this actor.
|
||||
*
|
||||
* An example of where this supervisor might be used is when you may have an actor that is
|
||||
* responsible for continuously polling on a server for some resource that sometimes may be down.
|
||||
* Instead of hammering the server continuously when the resource is unavailable, the actor will
|
||||
* be restarted with an exponentially increasing back off until the resource is available again.
|
||||
*
|
||||
* '''***
|
||||
* This supervisor should not be used with `Akka Persistence` child actors.
|
||||
* `Akka Persistence` actors shutdown unconditionally on `persistFailure()`s rather
|
||||
* than throw an exception on a failure like normal actors.
|
||||
* [[#onStop]] should be used instead for cases where the child actor
|
||||
* terminates itself as a failure signal instead of the normal behavior of throwing an exception.
|
||||
* ***'''
|
||||
* You can define another
|
||||
* supervision strategy by using `akka.pattern.BackoffOptions.withSupervisorStrategy` on [[akka.pattern.BackoffOptions]].
|
||||
* supervision strategy by using `akka.pattern.BackoffOptions.withSupervisorStrategy` on [[akka.pattern.BackoffOnFailureOptions]].
|
||||
*
|
||||
* @param childProps the [[akka.actor.Props]] of the child actor that
|
||||
* will be started and supervised
|
||||
|
|
@ -244,14 +114,13 @@ object Backoff {
|
|||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
*/
|
||||
@deprecated("Use the overloaded one which accepts maxNrOfRetries instead.", "2.5.17")
|
||||
def onFailure(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: java.time.Duration,
|
||||
maxBackoff: java.time.Duration,
|
||||
randomFactor: Double): BackoffOnFailureOptions =
|
||||
onFailure(childProps, childName, minBackoff.asScala, maxBackoff.asScala, randomFactor, -1)
|
||||
onFailure(childProps, childName, minBackoff.asScala, maxBackoff.asScala, randomFactor)
|
||||
|
||||
/**
|
||||
* Back-off options for creating a back-off supervisor actor that expects a child actor to stop on failure.
|
||||
|
|
@ -292,72 +161,7 @@ object Backoff {
|
|||
* if it wants to do an intentional stop.
|
||||
*
|
||||
* Exceptions in the child are handled with the default supervisionStrategy, which can be changed by using
|
||||
* [[BackoffOptions#withSupervisorStrategy]] or [[BackoffOptions#withDefaultStoppingStrategy]]. A
|
||||
* `Restart` will perform a normal immediate restart of the child. A `Stop` will
|
||||
* stop the child, but it will be started again after the back-off duration.
|
||||
*
|
||||
* @param childProps the [[akka.actor.Props]] of the child actor that
|
||||
* will be started and supervised
|
||||
* @param childName name of the child actor
|
||||
* @param minBackoff minimum (initial) duration until the child actor will
|
||||
* started again, if it is terminated
|
||||
* @param maxBackoff the exponential back-off is capped to this duration
|
||||
* @param randomFactor after calculation of the exponential back-off an additional
|
||||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
* @param maxNrOfRetries maximum number of attempts to restart the child actor.
|
||||
* The supervisor will terminate itself after the maxNoOfRetries is reached.
|
||||
* In order to restart infinitely pass in `-1`.
|
||||
*/
|
||||
def onStop(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: FiniteDuration,
|
||||
maxBackoff: FiniteDuration,
|
||||
randomFactor: Double,
|
||||
maxNrOfRetries: Int): BackoffOnStopOptions =
|
||||
BackoffOptionsImpl(StopImpliesFailure, childProps, childName, minBackoff, maxBackoff, randomFactor).withMaxNrOfRetries(maxNrOfRetries)
|
||||
|
||||
/**
|
||||
* Back-off options for creating a back-off supervisor actor that expects a child actor to stop on failure.
|
||||
*
|
||||
* This actor can be used to supervise a child actor and start it again
|
||||
* after a back-off duration if the child actor is stopped.
|
||||
*
|
||||
* This is useful in situations where the re-start of the child actor should be
|
||||
* delayed e.g. in order to give an external resource time to recover before the
|
||||
* child actor tries contacting it again (after being restarted).
|
||||
*
|
||||
* Specifically this pattern is useful for persistent actors,
|
||||
* which are stopped in case of persistence failures.
|
||||
* Just restarting them immediately would probably fail again (since the data
|
||||
* store is probably unavailable). It is better to try again after a delay.
|
||||
*
|
||||
* It supports exponential back-off between the given `minBackoff` and
|
||||
* `maxBackoff` durations. For example, if `minBackoff` is 3 seconds and
|
||||
* `maxBackoff` 30 seconds the start attempts will be delayed with
|
||||
* 3, 6, 12, 24, 30, 30 seconds. The exponential back-off counter is reset
|
||||
* if the actor is not terminated within the `minBackoff` duration.
|
||||
*
|
||||
* In addition to the calculated exponential back-off an additional
|
||||
* random delay based the given `randomFactor` is added, e.g. 0.2 adds up to 20%
|
||||
* delay. The reason for adding a random delay is to avoid that all failing
|
||||
* actors hit the backend resource at the same time.
|
||||
*
|
||||
* You can retrieve the current child `ActorRef` by sending `BackoffSupervisor.GetCurrentChild`
|
||||
* message to this actor and it will reply with [[akka.pattern.BackoffSupervisor.CurrentChild]]
|
||||
* containing the `ActorRef` of the current child, if any.
|
||||
*
|
||||
* The `BackoffSupervisor`delegates all messages from the child to the parent of the
|
||||
* `BackoffSupervisor`, with the supervisor as sender.
|
||||
*
|
||||
* The `BackoffSupervisor` forwards all other messages to the child, if it is currently running.
|
||||
*
|
||||
* The child can stop itself and send a [[akka.actor.PoisonPill]] to the parent supervisor
|
||||
* if it wants to do an intentional stop.
|
||||
*
|
||||
* Exceptions in the child are handled with the default supervisionStrategy, which can be changed by using
|
||||
* [[BackoffOptions#withSupervisorStrategy]] or [[BackoffOptions#withDefaultStoppingStrategy]]. A
|
||||
* [[BackoffOnStopOptions#withSupervisorStrategy]] or [[BackoffOnStopOptions#withDefaultStoppingStrategy]]. A
|
||||
* `Restart` will perform a normal immediate restart of the child. A `Stop` will
|
||||
* stop the child, but it will be started again after the back-off duration.
|
||||
*
|
||||
|
|
@ -377,7 +181,7 @@ object Backoff {
|
|||
minBackoff: FiniteDuration,
|
||||
maxBackoff: FiniteDuration,
|
||||
randomFactor: Double): BackoffOnStopOptions =
|
||||
BackoffOptionsImpl(StopImpliesFailure, childProps, childName, minBackoff, maxBackoff, randomFactor)
|
||||
BackoffOnStopOptionsImpl(childProps, childName, minBackoff, maxBackoff, randomFactor)
|
||||
|
||||
/**
|
||||
* Java API: Back-off options for creating a back-off supervisor actor that expects a child actor to stop on failure.
|
||||
|
|
@ -418,72 +222,7 @@ object Backoff {
|
|||
* if it wants to do an intentional stop.
|
||||
*
|
||||
* Exceptions in the child are handled with the default supervisionStrategy, which can be changed by using
|
||||
* [[BackoffOptions#withSupervisorStrategy]] or [[BackoffOptions#withDefaultStoppingStrategy]]. A
|
||||
* `Restart` will perform a normal immediate restart of the child. A `Stop` will
|
||||
* stop the child, but it will be started again after the back-off duration.
|
||||
*
|
||||
* @param childProps the [[akka.actor.Props]] of the child actor that
|
||||
* will be started and supervised
|
||||
* @param childName name of the child actor
|
||||
* @param minBackoff minimum (initial) duration until the child actor will
|
||||
* started again, if it is terminated
|
||||
* @param maxBackoff the exponential back-off is capped to this duration
|
||||
* @param randomFactor after calculation of the exponential back-off an additional
|
||||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
* @param maxNrOfRetries maximum number of attempts to restart the child actor.
|
||||
* The supervisor will terminate itself after the maxNoOfRetries is reached.
|
||||
* In order to restart infinitely pass in `-1`.
|
||||
*/
|
||||
def onStop(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: java.time.Duration,
|
||||
maxBackoff: java.time.Duration,
|
||||
randomFactor: Double,
|
||||
maxNrOfRetries: Int): BackoffOnStopOptions =
|
||||
onStop(childProps, childName, minBackoff.asScala, maxBackoff.asScala, randomFactor, maxNrOfRetries)
|
||||
|
||||
/**
|
||||
* Java API: Back-off options for creating a back-off supervisor actor that expects a child actor to stop on failure.
|
||||
*
|
||||
* This actor can be used to supervise a child actor and start it again
|
||||
* after a back-off duration if the child actor is stopped.
|
||||
*
|
||||
* This is useful in situations where the re-start of the child actor should be
|
||||
* delayed e.g. in order to give an external resource time to recover before the
|
||||
* child actor tries contacting it again (after being restarted).
|
||||
*
|
||||
* Specifically this pattern is useful for persistent actors,
|
||||
* which are stopped in case of persistence failures.
|
||||
* Just restarting them immediately would probably fail again (since the data
|
||||
* store is probably unavailable). It is better to try again after a delay.
|
||||
*
|
||||
* It supports exponential back-off between the given `minBackoff` and
|
||||
* `maxBackoff` durations. For example, if `minBackoff` is 3 seconds and
|
||||
* `maxBackoff` 30 seconds the start attempts will be delayed with
|
||||
* 3, 6, 12, 24, 30, 30 seconds. The exponential back-off counter is reset
|
||||
* if the actor is not terminated within the `minBackoff` duration.
|
||||
*
|
||||
* In addition to the calculated exponential back-off an additional
|
||||
* random delay based the given `randomFactor` is added, e.g. 0.2 adds up to 20%
|
||||
* delay. The reason for adding a random delay is to avoid that all failing
|
||||
* actors hit the backend resource at the same time.
|
||||
*
|
||||
* You can retrieve the current child `ActorRef` by sending `BackoffSupervisor.GetCurrentChild`
|
||||
* message to this actor and it will reply with [[akka.pattern.BackoffSupervisor.CurrentChild]]
|
||||
* containing the `ActorRef` of the current child, if any.
|
||||
*
|
||||
* The `BackoffSupervisor`delegates all messages from the child to the parent of the
|
||||
* `BackoffSupervisor`, with the supervisor as sender.
|
||||
*
|
||||
* The `BackoffSupervisor` forwards all other messages to the child, if it is currently running.
|
||||
*
|
||||
* The child can stop itself and send a [[akka.actor.PoisonPill]] to the parent supervisor
|
||||
* if it wants to do an intentional stop.
|
||||
*
|
||||
* Exceptions in the child are handled with the default supervisionStrategy, which can be changed by using
|
||||
* [[BackoffOptions#withSupervisorStrategy]] or [[BackoffOptions#withDefaultStoppingStrategy]]. A
|
||||
* [[BackoffOnStopOptions#withSupervisorStrategy]] or [[BackoffOnStopOptions#withDefaultStoppingStrategy]]. A
|
||||
* `Restart` will perform a normal immediate restart of the child. A `Stop` will
|
||||
* stop the child, but it will be started again after the back-off duration.
|
||||
*
|
||||
|
|
@ -497,79 +236,69 @@ object Backoff {
|
|||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
*/
|
||||
@deprecated("Use the overloaded one which accepts maxNrOfRetries instead.", "2.5.17")
|
||||
def onStop(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: java.time.Duration,
|
||||
maxBackoff: java.time.Duration,
|
||||
randomFactor: Double): BackoffOnStopOptions =
|
||||
onStop(childProps, childName, minBackoff.asScala, maxBackoff.asScala, randomFactor, -1)
|
||||
|
||||
onStop(childProps, childName, minBackoff.asScala, maxBackoff.asScala, randomFactor)
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures a back-off supervisor actor. Start with `Backoff.onStop` or `Backoff.onFailure`.
|
||||
* BackoffOptions is immutable, so be sure to chain methods like:
|
||||
* {{{
|
||||
* val options = Backoff.onFailure(childProps, childName, minBackoff, maxBackoff, randomFactor)
|
||||
* .withManualReset
|
||||
* context.actorOf(BackoffSupervisor.props(options), name)
|
||||
* }}}
|
||||
*/
|
||||
@DoNotInherit
|
||||
trait BackoffOptions {
|
||||
private[akka] sealed trait ExtendedBackoffOptions[T <: ExtendedBackoffOptions[T]] {
|
||||
|
||||
/**
|
||||
* Returns a new BackoffOptions with automatic back-off reset.
|
||||
* The back-off algorithm is reset if the child does not crash within the specified `resetBackoff`.
|
||||
*
|
||||
* @param resetBackoff The back-off is reset if the child does not crash within this duration.
|
||||
*/
|
||||
def withAutoReset(resetBackoff: FiniteDuration): BackoffOptions
|
||||
def withAutoReset(resetBackoff: FiniteDuration): T
|
||||
|
||||
/**
|
||||
* Returns a new BackoffOptions with manual back-off reset. The back-off is only reset
|
||||
* if the child sends a `BackoffSupervisor.Reset` to its parent (the backoff-supervisor actor).
|
||||
*/
|
||||
def withManualReset: BackoffOptions
|
||||
def withManualReset: T
|
||||
|
||||
/**
|
||||
* Returns a new BackoffOptions with the supervisorStrategy.
|
||||
*
|
||||
* @param supervisorStrategy the supervisorStrategy that the back-off supervisor will use.
|
||||
* The default supervisor strategy is used as fallback if the specified supervisorStrategy (its decider)
|
||||
* does not explicitly handle an exception. As the BackoffSupervisor creates a separate actor to handle the
|
||||
* backoff process, only a [[OneForOneStrategy]] makes sense here.
|
||||
* Note that changing the strategy will replace the previously defined maxNrOfRetries.
|
||||
*/
|
||||
def withSupervisorStrategy(supervisorStrategy: OneForOneStrategy): BackoffOptions
|
||||
def withSupervisorStrategy(supervisorStrategy: OneForOneStrategy): T
|
||||
|
||||
/**
|
||||
* Returns a new BackoffOptions with a default `SupervisorStrategy.stoppingStrategy`.
|
||||
* The default supervisor strategy is used as fallback for throwables not handled by `SupervisorStrategy.stoppingStrategy`.
|
||||
*/
|
||||
def withDefaultStoppingStrategy: BackoffOptions
|
||||
def withDefaultStoppingStrategy: T
|
||||
|
||||
/**
|
||||
* Returns a new BackoffOptions with a maximum number of retries to restart the child actor.
|
||||
* By default, the supervisor will retry infinitely.
|
||||
* With this option, the supervisor will terminate itself after the maxNoOfRetries is reached.
|
||||
*
|
||||
* @param maxNrOfRetries the number of times a child actor is allowed to be restarted.
|
||||
* If negative, the value is unbounded, otherwise the provided
|
||||
* limit is used. If the limit is exceeded the child actor will be stopped.
|
||||
*/
|
||||
def withMaxNrOfRetries(maxNrOfRetries: Int): BackoffOptions
|
||||
def withMaxNrOfRetries(maxNrOfRetries: Int): T
|
||||
|
||||
/**
|
||||
* Returns a new BackoffOptions with a constant reply to messages that the supervisor receives while its
|
||||
* child is stopped. By default, a message received while the child is stopped is forwarded to `deadLetters`.
|
||||
* With this option, the supervisor will reply to the sender instead.
|
||||
*
|
||||
* @param replyWhileStopped The message that the supervisor will send in response to all messages while
|
||||
* its child is stopped.
|
||||
*/
|
||||
def withReplyWhileStopped(replyWhileStopped: Any): BackoffOptions
|
||||
|
||||
// for backwards compability with 2.5.19
|
||||
@deprecated("Use through BackoffOnStopOptions instead of BackoffOptions", since = "2.5.20")
|
||||
def withFinalStopMessage(isFinalStopMessage: Any ⇒ Boolean): BackoffOptions
|
||||
def withReplyWhileStopped(replyWhileStopped: Any): T
|
||||
|
||||
/**
|
||||
* Returns the props to create the back-off supervisor.
|
||||
|
|
@ -577,7 +306,8 @@ trait BackoffOptions {
|
|||
private[akka] def props: Props
|
||||
}
|
||||
|
||||
sealed trait BackoffOnStopOptions extends BackoffOptions {
|
||||
@DoNotInherit
|
||||
sealed trait BackoffOnStopOptions extends ExtendedBackoffOptions[BackoffOnStopOptions] {
|
||||
|
||||
/**
|
||||
* Predicate evaluated for each message, if it returns true and the supervised actor is
|
||||
|
|
@ -585,17 +315,13 @@ sealed trait BackoffOnStopOptions extends BackoffOptions {
|
|||
* the supervised actor is running then it will be forwarded to the supervised actor and
|
||||
* when the supervised actor stops its self the supervisor will stop its self.
|
||||
*/
|
||||
def withFinalStopMessage(isFinalStopMessage: Any ⇒ Boolean): BackoffOptions
|
||||
def withFinalStopMessage(isFinalStopMessage: Any ⇒ Boolean): BackoffOnStopOptions
|
||||
}
|
||||
|
||||
sealed trait BackoffOnFailureOptions extends BackoffOptions {
|
||||
// for backwards compability with 2.5.19
|
||||
@deprecated("This has no effect for backoff on failure", since = "2.5.20")
|
||||
def withFinalStopMessage(isFinalStopMessage: Any ⇒ Boolean): BackoffOptions
|
||||
}
|
||||
@DoNotInherit
|
||||
sealed trait BackoffOnFailureOptions extends ExtendedBackoffOptions[BackoffOnFailureOptions]
|
||||
|
||||
private final case class BackoffOptionsImpl(
|
||||
backoffType: BackoffType = RestartImpliesFailure,
|
||||
private final case class BackoffOnStopOptionsImpl[T](
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: FiniteDuration,
|
||||
|
|
@ -605,7 +331,7 @@ private final case class BackoffOptionsImpl(
|
|||
supervisorStrategy: OneForOneStrategy = OneForOneStrategy()(SupervisorStrategy.defaultStrategy.decider),
|
||||
replyWhileStopped: Option[Any] = None,
|
||||
finalStopMessage: Option[Any ⇒ Boolean] = None
|
||||
) extends BackoffOptions with BackoffOnStopOptions with BackoffOnFailureOptions {
|
||||
) extends BackoffOnStopOptions {
|
||||
|
||||
val backoffReset = reset.getOrElse(AutoReset(minBackoff))
|
||||
|
||||
|
|
@ -627,20 +353,43 @@ private final case class BackoffOptionsImpl(
|
|||
case _ ⇒ // ignore
|
||||
}
|
||||
|
||||
backoffType match {
|
||||
//onFailure method in companion object
|
||||
case RestartImpliesFailure ⇒
|
||||
Props(new BackoffOnRestartSupervisor(childProps, childName, minBackoff, maxBackoff, backoffReset, randomFactor, supervisorStrategy, replyWhileStopped))
|
||||
//onStop method in companion object
|
||||
case StopImpliesFailure ⇒
|
||||
Props(new BackoffOnStopSupervisor(childProps, childName, minBackoff, maxBackoff, backoffReset, randomFactor, supervisorStrategy, replyWhileStopped, finalStopMessage))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed trait BackoffType
|
||||
private final case object StopImpliesFailure extends BackoffType
|
||||
private final case object RestartImpliesFailure extends BackoffType
|
||||
private final case class BackoffOnFailureOptionsImpl[T](
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
minBackoff: FiniteDuration,
|
||||
maxBackoff: FiniteDuration,
|
||||
randomFactor: Double,
|
||||
reset: Option[BackoffReset] = None,
|
||||
supervisorStrategy: OneForOneStrategy = OneForOneStrategy()(SupervisorStrategy.defaultStrategy.decider),
|
||||
replyWhileStopped: Option[Any] = None
|
||||
) extends BackoffOnFailureOptions {
|
||||
|
||||
val backoffReset = reset.getOrElse(AutoReset(minBackoff))
|
||||
|
||||
def withAutoReset(resetBackoff: FiniteDuration) = copy(reset = Some(AutoReset(resetBackoff)))
|
||||
def withManualReset = copy(reset = Some(ManualReset))
|
||||
def withSupervisorStrategy(supervisorStrategy: OneForOneStrategy) = copy(supervisorStrategy = supervisorStrategy)
|
||||
def withDefaultStoppingStrategy = copy(supervisorStrategy = OneForOneStrategy(supervisorStrategy.maxNrOfRetries)(SupervisorStrategy.stoppingStrategy.decider))
|
||||
def withReplyWhileStopped(replyWhileStopped: Any) = copy(replyWhileStopped = Some(replyWhileStopped))
|
||||
def withMaxNrOfRetries(maxNrOfRetries: Int) = copy(supervisorStrategy = supervisorStrategy.withMaxNrOfRetries(maxNrOfRetries))
|
||||
|
||||
def props = {
|
||||
require(minBackoff > Duration.Zero, "minBackoff must be > 0")
|
||||
require(maxBackoff >= minBackoff, "maxBackoff must be >= minBackoff")
|
||||
require(0.0 <= randomFactor && randomFactor <= 1.0, "randomFactor must be between 0.0 and 1.0")
|
||||
backoffReset match {
|
||||
case AutoReset(resetBackoff) ⇒
|
||||
require(minBackoff <= resetBackoff && resetBackoff <= maxBackoff)
|
||||
case _ ⇒ // ignore
|
||||
}
|
||||
|
||||
Props(new BackoffOnRestartSupervisor(childProps, childName, minBackoff, maxBackoff, backoffReset, randomFactor, supervisorStrategy, replyWhileStopped))
|
||||
}
|
||||
}
|
||||
|
||||
private[akka] sealed trait BackoffReset
|
||||
private[akka] final case object ManualReset extends BackoffReset
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ object BackoffSupervisor {
|
|||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
*/
|
||||
@deprecated("Use props with BackoffOptions instead", since = "2.5.20")
|
||||
def props(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
|
|
@ -61,6 +62,7 @@ object BackoffSupervisor {
|
|||
* The supervisor will terminate itself after the maxNoOfRetries is reached.
|
||||
* In order to restart infinitely pass in `-1`.
|
||||
*/
|
||||
@deprecated("Use props with BackoffOptions instead", since = "2.5.20")
|
||||
def props(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
|
|
@ -92,6 +94,7 @@ object BackoffSupervisor {
|
|||
* random delay based on this factor is added, e.g. `0.2` adds up to `20%` delay.
|
||||
* In order to skip this additional delay pass in `0`.
|
||||
*/
|
||||
@deprecated("Use props with BackoffOptions instead", since = "2.5.20")
|
||||
def props(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
|
|
@ -121,6 +124,7 @@ object BackoffSupervisor {
|
|||
* The supervisor will terminate itself after the maxNoOfRetries is reached.
|
||||
* In order to restart infinitely pass in `-1`.
|
||||
*/
|
||||
@deprecated("Use props with BackoffOptions instead", since = "2.5.20")
|
||||
def props(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
|
|
@ -152,6 +156,7 @@ object BackoffSupervisor {
|
|||
* in the child. As the BackoffSupervisor creates a separate actor to handle the
|
||||
* backoff process, only a [[OneForOneStrategy]] makes sense here.
|
||||
*/
|
||||
@deprecated("Use props with BackoffOptions instead", since = "2.5.20")
|
||||
def propsWithSupervisorStrategy(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
|
|
@ -186,6 +191,7 @@ object BackoffSupervisor {
|
|||
* in the child. As the BackoffSupervisor creates a separate actor to handle the
|
||||
* backoff process, only a [[OneForOneStrategy]] makes sense here.
|
||||
*/
|
||||
@deprecated("Use props with BackoffOptions instead", since = "2.5.20")
|
||||
def propsWithSupervisorStrategy(
|
||||
childProps: Props,
|
||||
childName: String,
|
||||
|
|
@ -201,8 +207,23 @@ object BackoffSupervisor {
|
|||
*
|
||||
* @param options the [[BackoffOptions]] that specify how to construct a backoff-supervisor.
|
||||
*/
|
||||
@deprecated("Use new API from BackoffOptions object instead", since = "2.5.20")
|
||||
def props(options: BackoffOptions): Props = options.props
|
||||
|
||||
/**
|
||||
* Props for creating a `BackoffSupervisor` actor from [[BackoffOnStopOptions]].
|
||||
*
|
||||
* @param options the [[BackoffOnStopOptions]] that specify how to construct a backoff-supervisor.
|
||||
*/
|
||||
def props(options: BackoffOnStopOptions): Props = options.props
|
||||
|
||||
/**
|
||||
* Props for creating a `BackoffSupervisor` actor from [[BackoffOnFailureOptions]].
|
||||
*
|
||||
* @param options the [[BackoffOnFailureOptions]] that specify how to construct a backoff-supervisor.
|
||||
*/
|
||||
def props(options: BackoffOnFailureOptions): Props = options.props
|
||||
|
||||
/**
|
||||
* Send this message to the `BackoffSupervisor` and it will reply with
|
||||
* [[BackoffSupervisor.CurrentChild]] containing the `ActorRef` of the current child, if any.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue