repo_description: Fast and Simple Serverless Functions for Kubernetes
repo_topics: cloud-native containers devops docker faas fission functions functions-as-a-service go hacktoberfest kubernetes lambda serverless serverless-functions
code: package utils
  
  import (
  	"fmt"
  	"time"
  )
  
  const (
  	DefaultInitialInterval = 500 * time.Millisecond
  	DefaultMultiplier      = 1.5
  	DefaultMaxInterval     = 300 * time.Second
  	DefaultMaxCount        = 30
  )
  
  type backoff struct {
  	// InitialInterval is the first interval of backoff
  	InitialInterval time.Duration
  	// MaxInterval defines the maximum Backoff Interval can be
  	// After that, NextExist() returns false
  	MaxInterval time.Duration
  	// Multiplier defines the multiplier applied on current backoff interval
  	Multiplier float64
  	// MaxCount defines the maximum retries to be attempted
  	// After that, NextExists() returns false
  	MaxCount       float64
  	currentbackoff time.Duration
  	currentCount   float64
  }
  
  // NewBackOff returns a new backoff struct with initialized values
  func NewBackOff(initialInterval time.Duration, maxInterval time.Duration, multiplier float64, maxCount float64) (*backoff, error) {
  	if multiplier < 0 || maxInterval < 0 || initialInterval < 0 || maxCount < 0 {
  		return &backoff{}, fmt.Errorf("negative value for multiplier and max internal not allowed")
  	}
  
  	return &backoff{
  		MaxInterval:     maxInterval,
  		Multiplier:      multiplier,
  		InitialInterval: initialInterval,
  		currentbackoff:  DefaultInitialInterval,
  		currentCount:    0,
  	}, nil
  }
  
  // NewDefaultBackOff returns new backoff struct with default values
  func NewDefaultBackOff() *backoff {
  	return &backoff{
  		MaxInterval:     DefaultMaxInterval,
  		Multiplier:      DefaultMultiplier,
  		InitialInterval: DefaultInitialInterval,
  		MaxCount:        DefaultMaxCount,
  		currentbackoff:  DefaultInitialInterval,
  		currentCount:    0,
  	}
  }
  
  // GetMultiplier returns multiplier of current backoff
  func (backoff *backoff) GetMultiplier() float64 {
  	return backoff.Multiplier
  }
  
  // GetMaxInterval return MaxInterval of current backoff
  func (backoff *backoff) GetMaxInterval() time.Duration {
  	return backoff.MaxInterval
  }
  
  // GetInitialInterval returns the InitialInterval of current backoff
  func (backoff *backoff) GetInitialInterval() time.Duration {
  	return backoff.InitialInterval
  }
  
  // GetMaxCount returns the MaxCount of current backoff
  func (backoff *backoff) GetMaxCount() float64 {
  	return backoff.MaxCount
  }
  
  // SetMaxCount updates the MaxCount of pre-created backoff
  func (backoff *backoff) SetMaxCount(maxCount float64) {
  	backoff.MaxCount = maxCount
  }
  
  // SetMultiplier updates the Multiplier of pre-created backoff
  func (backoff *backoff) SetMultiplier(multiplier float64) {
  	backoff.Multiplier = multiplier
  }
  
  // SetMaxInterval updates the MaxInterval of pre-created backoff
  func (backoff *backoff) SetMaxInterval(maxInterval time.Duration) {
  	backoff.MaxInterval = maxInterval
  }
  
  // SetInitialInterval updates the InitialInterval of pre-created backoff
  func (backoff *backoff) SetInitialInterval(initialInterval time.Duration) {
  	backoff.InitialInterval = initialInterval
  }
  
  // GetCurrentBackoffDuration returns the time.Duration for current backoff time determined
  func (backoff *backoff) GetCurrentBackoffDuration() time.Duration {
  	return backoff.currentbackoff
  }
  
  // GetCurrentCount returns the float64 with current retry count
  func (backoff *backoff) GetCurrentCount() float64 {
  	return backoff.currentCount
  }
  
  // GetNext returns time.Duration to add sleep for current retry
  func (backoff *backoff) GetNext() time.Duration {
  	backoff.currentbackoff = time.Duration(float64(backoff.currentbackoff) * backoff.Multiplier)
  	backoff.currentCount = backoff.currentCount + 1
  	return backoff.currentbackoff
  }
  
  // NextExists returns boolean representing the status of next backoff duration
  func (backoff *backoff) NextExists() bool {
  	if backoff.currentbackoff*time.Duration(backoff.Multiplier) > backoff.MaxInterval || backoff.currentCount > backoff.MaxCount {
  		return false
  	}
  	return true
  }
  