Actor used to supervise actors with ability to restart them after back-off timeout occurred. It's designed for cases when i.e. persistent actor stops due to journal unavailability or failure. In this case it better to wait before restart.
Inheritance: Akka.Actor.UntypedActor
Example #1
0
        /// <summary>
        /// <para>
        /// Given a function, returns an internally retrying Task.
        /// The first attempt will be made immediately, each subsequent attempt will be made with a backoff time,
        /// if the previous attempt failed.
        /// </para>
        /// If attempts are exhausted the returned Task is simply the result of invoking attempt.
        /// </summary>
        /// <param name="attempt">TBD</param>
        /// <param name="attempts">TBD</param>
        /// <param name="minBackoff">minimum (initial) duration until the child actor will started again, if it is terminated.</param>
        /// <param name="maxBackoff">the exponential back-off is capped to this duration.</param>
        /// <param name="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>
        /// <param name="scheduler">The scheduler instance to use.</param>
        public static Task <T> Retry <T>(Func <Task <T> > attempt, int attempts, TimeSpan minBackoff, TimeSpan maxBackoff, int randomFactor, IScheduler scheduler)
        {
            if (attempt == null)
            {
                throw new ArgumentNullException("Parameter attempt should not be null.");
            }
            if (minBackoff <= TimeSpan.Zero)
            {
                throw new ArgumentException("Parameter minBackoff must be > 0");
            }
            if (maxBackoff < minBackoff)
            {
                throw new ArgumentException("Parameter maxBackoff must be >= minBackoff");
            }
            if (randomFactor < 0.0 || randomFactor > 1.0)
            {
                throw new ArgumentException("RandomFactor must be between 0.0 and 1.0");
            }

            return(Retry(attempt, attempts, attempted => BackoffSupervisor.CalculateDelay(attempted, minBackoff, maxBackoff, randomFactor), scheduler));
        }
Example #2
0
        private bool WaitChildTerminatedBeforeBackoff(object message, IActorRef childRef)
        {
            var terminated = message as Terminated;

            if (terminated != null && terminated.ActorRef.Equals(childRef))
            {
                Become(Receive);
                Child = null;
                var restartDelay = BackoffSupervisor.CalculateDelay(RestartCountN, _minBackoff, _maxBackoff, _randomFactor);
                Context.System.Scheduler.ScheduleTellOnce(restartDelay, Self, BackoffSupervisor.StartChild.Instance, Self);
                RestartCountN++;
            }
            else if (message is BackoffSupervisor.StartChild)
            {
                // Ignore it, we will schedule a new one once current child terminated.
            }
            else
            {
                return(false);
            }

            return(true);
        }
Example #3
0
        private bool WaitChildTerminatedBeforeBackoff(object message, IActorRef childRef)
        {
            switch (message)
            {
            case Terminated terminated when terminated.ActorRef.Equals(childRef):
            {
                Become(Receive);
                Child = null;
                var restartDelay = BackoffSupervisor.CalculateDelay(RestartCountN, _minBackoff, _maxBackoff, _randomFactor);
                Context.System.Scheduler.ScheduleTellOnce(restartDelay, Self, BackoffSupervisor.StartChild.Instance, Self);
                RestartCountN++;
                break;
            }

            case BackoffSupervisor.StartChild _:
                // Ignore it, we will schedule a new one once current child terminated.
                break;

            default:
                return(false);
            }

            return(true);
        }