github.com/fluxcd/go-git-providers@v0.19.3/gitprovider/testutils/retry.go (about)

     1  /*
     2  Copyright 2020 The Flux authors
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package testutils
    18  
    19  import (
    20  	"fmt"
    21  	"os"
    22  	"time"
    23  )
    24  
    25  // RetryI is an interface for retry operations
    26  type RetryI interface {
    27  	IsRetryable(err error, opDesc string) bool
    28  	SetTimeout(timeout time.Duration)
    29  	SetInterval(interval time.Duration)
    30  	SetBackoff(backoff time.Duration)
    31  	SetRetries(retries int)
    32  	Timeout() time.Duration
    33  	Interval() time.Duration
    34  	Backoff() time.Duration
    35  	Retries() int
    36  	Counter() int
    37  }
    38  
    39  // RetryOp is a retry operation
    40  type RetryOp struct {
    41  	RetryI
    42  	timeout  time.Duration
    43  	interval time.Duration
    44  	backoff  time.Duration
    45  	retries  int
    46  	counter  int
    47  }
    48  
    49  // Timeout returns the timeout for the retry operation
    50  func (r RetryOp) Timeout() time.Duration {
    51  	return r.timeout
    52  }
    53  
    54  // Interval returns the interval for the retry operation
    55  func (r RetryOp) Interval() time.Duration {
    56  	return r.interval
    57  }
    58  
    59  // Backoff returns the backoff for the retry operation
    60  func (r RetryOp) Backoff() time.Duration {
    61  	return r.backoff
    62  }
    63  
    64  // Retries returns the number of retries for the retry operation
    65  func (r RetryOp) Retries() int {
    66  	return r.retries
    67  }
    68  
    69  // Counter returns the number of times the operation has been retried
    70  func (r RetryOp) Counter() int {
    71  	return r.counter
    72  }
    73  
    74  // SetTimeout sets the timeout for the retry operation
    75  func (r RetryOp) SetTimeout(timeout time.Duration) {
    76  	r.timeout = timeout
    77  }
    78  
    79  // SetInterval sets the interval for the retry operation
    80  func (r RetryOp) SetInterval(interval time.Duration) {
    81  	r.interval = interval
    82  }
    83  
    84  // SetBackoff sets the backoff for the retry operation
    85  func (r RetryOp) SetBackoff(backoff time.Duration) {
    86  	r.backoff = backoff
    87  }
    88  
    89  // SetRetries sets the number of retries for the retry operation
    90  func (r RetryOp) SetRetries(retries int) {
    91  	r.retries = retries
    92  }
    93  
    94  // IsRetryable returns true if the operation is retryable
    95  func (r RetryOp) IsRetryable(err error, opDesc string) bool {
    96  	if err == nil {
    97  		return true
    98  	}
    99  
   100  	fmt.Fprintf(os.Stderr, "%s, failed, error: %s\n", opDesc, err)
   101  	if r.counter >= r.retries {
   102  		time.Sleep(r.backoff)
   103  		r.counter = 0
   104  	}
   105  	r.counter++
   106  	return false
   107  }
   108  
   109  // NewRetry returns a new retry operation
   110  func NewRetry() RetryI {
   111  	r := RetryOp{
   112  		retries:  10,
   113  		counter:  0,
   114  		timeout:  time.Second * 60,
   115  		interval: time.Second,
   116  		backoff:  time.Second * 10,
   117  	}
   118  	return r
   119  }