code: func NewBackoffFn(base, cap, jitter int) func(ctx context.Context) int {
  	if base < 2 {
  		// Top prevent panic in 'rand.Intn'.
  		base = 2
  	}
  	attempts := 0
  	lastSleep := base
  	return func(ctx context.Context) int {
  		var sleep int
  		switch jitter {
  		case NoJitter:
  			sleep = expo(base, cap, attempts)
  		case FullJitter:
  			v := expo(base, cap, attempts)
  			sleep = rand.Intn(v)
  		case EqualJitter:
  			v := expo(base, cap, attempts)
  			sleep = v/2 + rand.Intn(v/2)
  		case DecorrJitter:
  			sleep = int(math.Min(float64(cap), float64(base+rand.Intn(lastSleep*3-base))))
  		}
  		logutil.Logger(context.Background()).Debug("backoff",
  			zap.Int("base", base),
  			zap.Int("sleep", sleep))
  		select {
  		case <-time.After(time.Duration(sleep) * time.Millisecond):
  		case <-ctx.Done():
  		}
  
  		attempts++
  		lastSleep = sleep
  		return lastSleep
  	}
  }
docs: // NewBackoffFn creates a backoff func which implements exponential backoff with
  // optional jitters.
  // See http://www.awsarchitectureblog.com/2015/03/backoff.html