54 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			54 lines
		
	
	
		
			1.2 KiB
		
	
	
	
		
			Go
		
	
	
	
package try
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"github.com/jenkinsci/kubernetes-operator/internal/errors"
 | 
						|
	time2 "github.com/jenkinsci/kubernetes-operator/internal/time"
 | 
						|
)
 | 
						|
 | 
						|
// ErrTimeout is used when the set timeout has been reached.
 | 
						|
type ErrTimeout struct {
 | 
						|
	text  string
 | 
						|
	cause error
 | 
						|
}
 | 
						|
 | 
						|
func (e *ErrTimeout) Error() string {
 | 
						|
	return fmt.Sprintf("%s: %s", e.text, e.cause.Error())
 | 
						|
}
 | 
						|
 | 
						|
// Cause returns the error that caused ErrTimeout.
 | 
						|
func (e *ErrTimeout) Cause() error {
 | 
						|
	return e.cause
 | 
						|
}
 | 
						|
 | 
						|
// Format implements fmt.Formatter used by Sprint(f) or Fprint(f) etc.
 | 
						|
func (e *ErrTimeout) Format(s fmt.State, verb rune) {
 | 
						|
	errors.Format(e.cause, s, verb)
 | 
						|
}
 | 
						|
 | 
						|
// Until keeps trying until timeout or there is a result or an error.
 | 
						|
func Until(something func() (end bool, err error), tick, timeout time.Duration) error {
 | 
						|
	counter := 0
 | 
						|
	tickChan := time2.Every(tick)
 | 
						|
	timeoutChan := time.After(timeout)
 | 
						|
	var lastErr error
 | 
						|
	for {
 | 
						|
		select {
 | 
						|
		case <-tickChan:
 | 
						|
			end, err := something()
 | 
						|
			lastErr = err
 | 
						|
			if end {
 | 
						|
				return err
 | 
						|
			}
 | 
						|
			counter++
 | 
						|
		case <-timeoutChan:
 | 
						|
			return &ErrTimeout{
 | 
						|
				text:  fmt.Sprintf("timed out after: %s, tries: %d", timeout, counter),
 | 
						|
				cause: lastErr,
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |