// NewLinearBackoff creates a backoff interval generator which increases by a
// constant amount on each unsuccessful retry.
198789
func NewLinearBackoff(minInterval, addInterval, maxInterval time.Duration) Backoff {
	b := &linearBackoff{
		minInterval: minInterval,
		addInterval: addInterval,
		maxInterval: maxInterval,
	}

	b.Reset()
	return b
}
32421
func (b *URLBackoff) CalculateBackoff(actualUrl *url.URL) time.Duration {
	return b.Backoff.Get(b.baseUrlKey(actualUrl))
}
367714
func BackoffLinearWithJitter(waitBetween time.Duration, jitterFraction float64) BackoffFunc {
	return func(attempt uint) time.Duration {
		return backoffutils.JitterUp(waitBetween, jitterFraction)
	}
}
475182
func NewBackend(client *clientv3.Client, opts ...Option) *Backend {
	b := Backend{
		client: client,
	}

	for _, opt := range opts {
		opt(&b)
	}

	return &b
}
1242749
func DefaultBackoff(base, max float64, retries int) time.Duration {
	return Backoff(base, max, .2, 1.6, retries)
}
1075502
func LinearBackoff(i int) time.Duration {
	return time.Duration(i) * time.Second
}
1315065
func NewBackend(delegate audit.Backend, p policy.Checker) audit.Backend {
	return &Backend{
		policyChecker:   p,
		delegateBackend: delegate,
	}
}
1144386
func BackOff(attempts uint) int {
	upper := int(math.Min(float64(retryBackOffCap), float64(retryBackOffBase)*math.Pow(2.0, float64(attempts))))
	sleep := time.Duration(rand.Intn(upper)) * time.Millisecond
	time.Sleep(sleep)
	return int(sleep)
}
366391
func NewRollbackManager(ctx context.Context, logger log.Logger, backendsFunc func() []*MountEntry, router *Router, core *Core) *RollbackManager {
	r := &RollbackManager{
		logger:      logger,
		backends:    backendsFunc,
		router:      router,
		period:      rollbackPeriod,
		inflight:    make(map[string]*rollbackState),
		doneCh:      make(chan struct{}),
		shutdownCh:  make(chan struct{}),
		quitContext: ctx,
		core:        core,
	}
	return r
}
513493
func withBackoff(bs backoff.Strategy) DialOption {
	return newFuncDialOption(func(o *dialOptions) {
		o.bs = bs
	})
}
705731
func (c Client) newRetryTimer(maxRetry int, unit time.Duration, cap time.Duration, jitter float64, doneCh chan struct{}) <-chan int {
	attemptCh := make(chan int)

	// computes the exponential backoff duration according to
	// https://www.awsarchitectureblog.com/2015/03/backoff.html
	exponentialBackoffWait := func(attempt int) time.Duration {
		// normalize jitter to the range [0, 1.0]
		if jitter < NoJitter {
			jitter = NoJitter
		}
		if jitter > MaxJitter {
			jitter = MaxJitter
		}

		//sleep = random_between(0, min(cap, base * 2 ** attempt))
		sleep := unit * time.Duration(1<<uint(attempt))
		if sleep > cap {
			sleep = cap
		}
		if jitter != NoJitter {
			sleep -= time.Duration(c.random.Float64() * float64(sleep) * jitter)
		}
		return sleep
	}

	go func() {
		defer close(attemptCh)
		for i := 0; i < maxRetry; i++ {
			select {
			// Attempts start from 1.
			case attemptCh <- i + 1:
			case <-doneCh:
				// Stop the routine.
				return
			}
			time.Sleep(exponentialBackoffWait(i))
		}
	}()
	return attemptCh
}
420348
func RetryBackoff(retry int, minBackoff, maxBackoff time.Duration) time.Duration {
	if retry < 0 {
		retry = 0
	}

	backoff := minBackoff << uint(retry)
	if backoff > maxBackoff || backoff < minBackoff {
		backoff = maxBackoff
	}

	if backoff == 0 {
		return 0
	}
	return time.Duration(rand.Int63n(int64(backoff)))
}
574470
func NewBackend(c config.Config) (gateway.Gateway, error) {
	conf := c.NetworkServer.Gateway.Backend.GCPPubSub

	b := Backend{
		gatewayMarshaler:  make(map[lorawan.EUI64]marshaler.Type),
		uplinkFrameChan:   make(chan gw.UplinkFrame),
		gatewayStatsChan:  make(chan gw.GatewayStats),
		downlinkTXAckChan: make(chan gw.DownlinkTXAck),
		ctx:               context.Background(),
	}
	var err error
	var o []option.ClientOption

	b.ctx, b.cancel = context.WithCancel(b.ctx)

	if conf.CredentialsFile != "" {
		o = append(o, option.WithCredentialsFile(conf.CredentialsFile))
	}

	log.Info("gateway/gcp_pub_sub: setting up client")
	b.client, err = pubsub.NewClient(b.ctx, conf.ProjectID, o...)
	if err != nil {
		return nil, errors.Wrap(err, "gateway/gcp_pub_sub: new pubsub client error")
	}

	log.WithField("topic", conf.DownlinkTopicName).Info("gateway/gcp_pub_sub: setup downlink topic")
	b.downlinkTopic = b.client.Topic(conf.DownlinkTopicName)
	ok, err := b.downlinkTopic.Exists(b.ctx)
	if err != nil {
		return nil, errors.Wrap(err, "gateway/gcp_pub_sub: topic exists error")
	}
	if !ok {
		return nil, fmt.Errorf("gateway/gcp_pub_sub: downlink topic '%s' does not exist", conf.DownlinkTopicName)
	}

	log.WithField("topic", conf.UplinkTopicName).Info("gateway/gcp_pub_sub: setup uplink topic")
	b.uplinkTopic = b.client.Topic(conf.UplinkTopicName)
	ok, err = b.uplinkTopic.Exists(b.ctx)
	if err != nil {
		return nil, errors.Wrap(err, "gateway/gcp_pub_sub: topic exists error")
	}
	if !ok {
		return nil, fmt.Errorf("gateway/gcp_pub_sub: uplink topic '%s' does not exist", conf.UplinkTopicName)
	}

	upSubName := fmt.Sprintf(uplinkSubscriptionTmpl, conf.UplinkTopicName)

	log.WithField("subscription", upSubName).Info("gateway/gcp_pub_sub: check if uplink subscription exists")
	b.uplinkSubscription = b.client.Subscription(upSubName)
	ok, err = b.uplinkSubscription.Exists(b.ctx)
	if err != nil {
		return nil, errors.Wrap(err, "gateway/gcp_pub_sub: subscription exists error")
	}

	// try to create the subscription if it doesn't exist
	if !ok {
		log.WithField("subscription", upSubName).Info("gateway/gcp_pub_sub: create uplink subscription")
		b.uplinkSubscription, err = b.client.CreateSubscription(b.ctx, upSubName, pubsub.SubscriptionConfig{
			Topic:             b.uplinkTopic,
			RetentionDuration: conf.UplinkRetentionDuration,
		})
	}

	// consume uplink frames
	go func() {
		for {
			err := b.uplinkSubscription.Receive(b.ctx, b.receiveFunc)
			if err != nil {
				log.WithError(err).Error("gateway/gcp_pub_sub: receive error")
				time.Sleep(time.Second * 2)
				continue
			}

			break
		}
	}()

	return &b, nil
}
1268262
func NewLinearRing(coords ...Coord) (*Geometry, error) {
	cs, err := coordSeqFromSlice(coords)
	if err != nil {
		return nil, err
	}
	return geomFromCoordSeq(cs, "NewLinearRing", cGEOSGeom_createLinearRing)
}
253267
func BackoffNanos(
	retry int,
	jitter bool,
	backoffFactor float64,
	initialBackoff time.Duration,
	maxBackoff time.Duration,
	rngFn RngFn,
) int64 {
	backoff := initialBackoff.Nanoseconds()
	if retry >= 1 {
		backoffFloat64 := float64(backoff) * math.Pow(backoffFactor, float64(retry-1))
		// math.Inf is also larger than math.MaxInt64.
		if backoffFloat64 > math.MaxInt64 {
			return maxBackoff.Nanoseconds()
		}
		backoff = int64(backoffFloat64)
	}
	// Validate the value of backoff to make sure Int63n() does not panic.
	if jitter && backoff >= 2 {
		half := backoff / 2
		backoff = half + rngFn(half)
	}
	if maxBackoff := maxBackoff.Nanoseconds(); backoff > maxBackoff {
		backoff = maxBackoff
	}
	return backoff
}
1184189
func newExponentialBackoff() *exponentialBackoff {
	b := &backoff.Backoff{
		Min:    DefaultMinBackoff,
		Max:    DefaultMaxBackoff,
		Jitter: true,
	}
	return &exponentialBackoff{b: *b, currentDelay: b.Duration()}
}
921451
func nextBackoff(backoff float64) float64 {
	if backoff < 0.5 {
		backoff = 0.5
	}

	backoff = backoff * 1.15 * (1.0 + rand.Float64())
	if backoff > 120 {
		backoff = 120
	} else if backoff < 0.5 {
		backoff = 0.5
	}

	return backoff
}