github.com/asynkron/protoactor-go@v0.0.0-20240308120642-ef91a6abee75/actor/strategy_exponential_backoff.go (about) 1 package actor 2 3 import ( 4 "math/rand" 5 "time" 6 ) 7 8 // NewExponentialBackoffStrategy creates a new Supervisor strategy that restarts a faulting child using an exponential 9 // back off algorithm: 10 // 11 // delay = 12 func NewExponentialBackoffStrategy(backoffWindow time.Duration, initialBackoff time.Duration) SupervisorStrategy { 13 return &exponentialBackoffStrategy{ 14 backoffWindow: backoffWindow, 15 initialBackoff: initialBackoff, 16 } 17 } 18 19 type exponentialBackoffStrategy struct { 20 backoffWindow time.Duration 21 initialBackoff time.Duration 22 } 23 24 var _ SupervisorStrategy = &exponentialBackoffStrategy{} 25 26 func (strategy *exponentialBackoffStrategy) HandleFailure(actorSystem *ActorSystem, supervisor Supervisor, child *PID, rs *RestartStatistics, reason interface{}, _ interface{}) { 27 strategy.setFailureCount(rs) 28 29 backoff := rs.FailureCount() * int(strategy.initialBackoff.Nanoseconds()) 30 noise := rand.Intn(500) 31 dur := time.Duration(backoff + noise) 32 time.AfterFunc(dur, func() { 33 logFailure(actorSystem, child, reason, RestartDirective) 34 supervisor.RestartChildren(child) 35 }) 36 } 37 38 func (strategy *exponentialBackoffStrategy) setFailureCount(rs *RestartStatistics) { 39 if rs.NumberOfFailures(strategy.backoffWindow) == 0 { 40 rs.Reset() 41 } 42 43 rs.Fail() 44 }