github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/rpc/retry.go (about)

     1  package rpc
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/cenkalti/backoff"
     7  	"github.com/twitchtv/twirp"
     8  
     9  	"github.com/devseccon/trivy/pkg/log"
    10  )
    11  
    12  const (
    13  	maxRetries = 10
    14  )
    15  
    16  // Retry executes the function again using backoff until maxRetries or success
    17  func Retry(f func() error) error {
    18  	operation := func() error {
    19  		err := f()
    20  		if err != nil {
    21  			twerr, ok := err.(twirp.Error)
    22  			if !ok {
    23  				return backoff.Permanent(err)
    24  			}
    25  			if twerr.Code() == twirp.Unavailable {
    26  				return err
    27  			}
    28  			return backoff.Permanent(err)
    29  		}
    30  		return nil
    31  	}
    32  
    33  	b := backoff.WithMaxRetries(backoff.NewExponentialBackOff(), maxRetries)
    34  	err := backoff.RetryNotify(operation, b, func(err error, _ time.Duration) {
    35  		log.Logger.Warn(err)
    36  		log.Logger.Info("Retrying HTTP request...")
    37  	})
    38  	if err != nil {
    39  		return err
    40  	}
    41  	return nil
    42  }