예제 #1
0
// delay delays a join attempt by sleeping for an amount of time. The
// amount of time is computed as an exponential backoff based on the number
// of join attempts that have been made at the time of the function call;
// the number of attempts is 0-based. It returns a time.Duration equal to the
// amount of delay applied.
func (d *exponentialDelayer) delay() time.Duration {
	// Convert durations to time in millis
	initialDelayMs := float64(util.MS(d.initialDelay))
	maxDelayMs := float64(util.MS(d.maxDelay))

	// Compute uncapped exponential delay (exponent is the number of join
	// attempts so far). Then, make sure the computed delay is capped at its
	// max. Apply a random jitter to the actual sleep duration and finally,
	// sleep.
	uncappedDelay := initialDelayMs * math.Pow(2, float64(d.numDelays))
	cappedDelay := math.Min(maxDelayMs, uncappedDelay)

	// If cappedDelay and nextDelayMin are equal, we have reached the point
	// at which the exponential backoff has reached its max; apply no more
	// jitter.
	var jitteredDelay int
	if cappedDelay == d.nextDelayMin {
		jitteredDelay = int(cappedDelay)
	} else {
		jitteredDelay = d.randomizer(int(cappedDelay-d.nextDelayMin)) + int(d.nextDelayMin)
	}

	// If this is the first time an uncapped delay reached or exceeded the
	// maximum allowable delay, log a message.
	if uncappedDelay >= maxDelayMs && d.maxDelayReached == false {
		d.logger.WithFields(bark.Fields{
			"numDelays":     d.numDelays,
			"initialDelay":  d.initialDelay,
			"minDelay":      d.nextDelayMin,
			"maxDelay":      d.maxDelay,
			"uncappedDelay": uncappedDelay,
			"cappedDelay":   cappedDelay,
			"jitteredDelay": jitteredDelay,
		}).Warn("ringpop join attempt delay reached max")
		d.maxDelayReached = true
	}

	// Set lower-bound for next attempt to maximum of current attempt.
	d.nextDelayMin = cappedDelay

	sleepDuration := time.Duration(jitteredDelay) * time.Millisecond
	d.sleeper(sleepDuration)

	// Increment the exponent used for backoff calculation.
	d.numDelays++

	return sleepDuration
}
예제 #2
0
func (s *dummmyStats) RecordTimer(key string, tags bark.Tags, d time.Duration) {
	s.vals[key] += util.MS(d)
}