github.com/Rookout/GoSDK@v0.1.48/pkg/utils/simple_backoff.go (about)

     1  package utils
     2  
     3  import "time"
     4  
     5  type Backoff struct {
     6  	currentBackoff time.Duration
     7  	maxBackoff     time.Duration
     8  }
     9  
    10  type BackoffOption interface {
    11  	Apply(*Backoff)
    12  }
    13  
    14  type MaxBackoffOption struct {
    15  	maxBackoff time.Duration
    16  }
    17  
    18  func (m MaxBackoffOption) Apply(backoff *Backoff) {
    19  	backoff.maxBackoff = m.maxBackoff
    20  }
    21  
    22  func WithMaxBackoff(maxBackoff time.Duration) MaxBackoffOption {
    23  	return MaxBackoffOption{maxBackoff: maxBackoff}
    24  }
    25  
    26  type InitialBackoff struct {
    27  	initialBackoff time.Duration
    28  }
    29  
    30  func (i InitialBackoff) Apply(backoff *Backoff) {
    31  	backoff.currentBackoff = i.initialBackoff
    32  }
    33  
    34  func WithInitialBackoff(initialBackoff time.Duration) InitialBackoff {
    35  	return InitialBackoff{initialBackoff: initialBackoff}
    36  }
    37  
    38  const defaultBackoff = 1 * time.Second
    39  
    40  
    41  func NewBackoff(opts ...BackoffOption) *Backoff {
    42  	b := &Backoff{}
    43  	for _, opt := range opts {
    44  		opt.Apply(b)
    45  	}
    46  	return b
    47  }
    48  
    49  func (b *Backoff) NextBackoff() time.Duration {
    50  	if b.currentBackoff == 0 {
    51  		b.currentBackoff = defaultBackoff
    52  	}
    53  
    54  	newBackoff := b.currentBackoff * 2
    55  	if b.maxBackoff != 0 {
    56  		if newBackoff > b.maxBackoff {
    57  			newBackoff = b.maxBackoff
    58  		}
    59  	}
    60  
    61  	b.currentBackoff = newBackoff
    62  	return b.currentBackoff
    63  }
    64  
    65  func (b *Backoff) MaxBackoff() time.Duration {
    66  	return b.maxBackoff
    67  }