func withRetry()

in image/resources/knfsd-fsidd/retry.go [29:69]


func withRetry(ctx context.Context, fn func() error) error {
	deadline := time.Now().Add(5 * time.Minute)
	backoff := &gax.Backoff{
		// Because of jitter, this will pick a time between 1ns and Interval
		// Keeping the initial interval small as the kernel is waiting for this
		// response. Though not too small otherwise it's likely to cause another
		// collision and have to retry again.
		Initial:    50 * time.Millisecond,
		Max:        60 * time.Second,
		Multiplier: 2,
	}

	// Keep retrying until the deadline is reached.
	var err error
	for {
		// Not interrupting an attempt once it has started, the deadline only
		// applies to the sleep/retry loop.
		err = fn()
		if err == nil {
			return nil
		}
		if !ShouldRetry(err) {
			return err
		}

		pause := backoff.Pause()
		// Check there's enough time remaining before the deadline for another attempt.
		if !time.Now().Add(pause).Before(deadline) {
			return err
		}

		log.Debug.Printf("[%d] RETRY (%s): %v", log.ID(ctx), pause, err)

		// Allow sleep to be interrupted by the context being cancelled to allow
		// for graceful shutdown.
		err = sleep(ctx, pause)
		if err != nil {
			return err
		}
	}
}