go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/sdk/supervisor/restart_policy.go (about)

     1  /*
     2  
     3  Copyright (c) 2024 - Present. Will Charczuk. All rights reserved.
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository.
     5  
     6  */
     7  
     8  package supervisor
     9  
    10  import (
    11  	"context"
    12  	"time"
    13  )
    14  
    15  // RestartPolicy is a type that accepts a service history and returns answers to common questions.
    16  type RestartPolicy interface {
    17  	ShouldRestart(context.Context, *ServiceHistory) bool
    18  	Delay(context.Context, *ServiceHistory) time.Duration
    19  }
    20  
    21  // RestartPolicySuccessiveFailures is a restart policy that will allow
    22  // the process to restart some number of times on error, after which
    23  // the supervisor will exit completely.
    24  //
    25  // This policy will also delay restarts by 500ms per successive failure.
    26  func RestartPolicySuccessiveFailures(successiveFailures int) RestartPolicy {
    27  	return &restartPolicyFuncs{
    28  		shouldRestart: func(_ context.Context, history *ServiceHistory) bool {
    29  			return len(history.RecentFailures()) < successiveFailures
    30  		},
    31  		delay: func(_ context.Context, history *ServiceHistory) time.Duration {
    32  			numberOfRecentFailures := time.Duration(len(history.RecentFailures()))
    33  			return numberOfRecentFailures * 500 * time.Millisecond
    34  		},
    35  	}
    36  }
    37  
    38  type restartPolicyFuncs struct {
    39  	shouldRestart func(context.Context, *ServiceHistory) bool
    40  	delay         func(context.Context, *ServiceHistory) time.Duration
    41  }
    42  
    43  func (rp restartPolicyFuncs) ShouldRestart(ctx context.Context, history *ServiceHistory) bool {
    44  	if rp.shouldRestart != nil {
    45  		return rp.shouldRestart(ctx, history)
    46  	}
    47  	return false
    48  }
    49  
    50  func (rp restartPolicyFuncs) Delay(ctx context.Context, history *ServiceHistory) time.Duration {
    51  	if rp.shouldRestart != nil {
    52  		return rp.delay(ctx, history)
    53  	}
    54  	return 500 * time.Millisecond
    55  }