Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • ai3/tools/acmeserver
  • godog/acmeserver
  • svp-bot/acmeserver
3 results
Select Git revision
Show changes
Showing
with 210 additions and 113 deletions
...@@ -20,3 +20,6 @@ _cgo_export.* ...@@ -20,3 +20,6 @@ _cgo_export.*
_testmain.go _testmain.go
*.exe *.exe
# IDEs
.idea/
language: go language: go
go: go:
- 1.7 - 1.13
- 1.x - 1.x
- tip - tip
before_install: before_install:
......
...@@ -9,7 +9,9 @@ The retries exponentially increase and stop increasing when a certain threshold ...@@ -9,7 +9,9 @@ The retries exponentially increase and stop increasing when a certain threshold
## Usage ## Usage
See https://godoc.org/github.com/cenkalti/backoff#pkg-examples Import path is `github.com/cenkalti/backoff/v4`. Please note the version part at the end.
Use https://pkg.go.dev/github.com/cenkalti/backoff/v4 to view the documentation.
## Contributing ## Contributing
...@@ -17,7 +19,7 @@ See https://godoc.org/github.com/cenkalti/backoff#pkg-examples ...@@ -17,7 +19,7 @@ See https://godoc.org/github.com/cenkalti/backoff#pkg-examples
* Please don't send a PR without opening an issue and discussing it first. * Please don't send a PR without opening an issue and discussing it first.
* If proposed change is not a common use case, I will probably not accept it. * If proposed change is not a common use case, I will probably not accept it.
[godoc]: https://godoc.org/github.com/cenkalti/backoff [godoc]: https://pkg.go.dev/github.com/cenkalti/backoff/v4
[godoc image]: https://godoc.org/github.com/cenkalti/backoff?status.png [godoc image]: https://godoc.org/github.com/cenkalti/backoff?status.png
[travis]: https://travis-ci.org/cenkalti/backoff [travis]: https://travis-ci.org/cenkalti/backoff
[travis image]: https://travis-ci.org/cenkalti/backoff.png?branch=master [travis image]: https://travis-ci.org/cenkalti/backoff.png?branch=master
...@@ -27,4 +29,4 @@ See https://godoc.org/github.com/cenkalti/backoff#pkg-examples ...@@ -27,4 +29,4 @@ See https://godoc.org/github.com/cenkalti/backoff#pkg-examples
[google-http-java-client]: https://github.com/google/google-http-java-client/blob/da1aa993e90285ec18579f1553339b00e19b3ab5/google-http-client/src/main/java/com/google/api/client/util/ExponentialBackOff.java [google-http-java-client]: https://github.com/google/google-http-java-client/blob/da1aa993e90285ec18579f1553339b00e19b3ab5/google-http-client/src/main/java/com/google/api/client/util/ExponentialBackOff.java
[exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff [exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff
[advanced example]: https://godoc.org/github.com/cenkalti/backoff#example_ [advanced example]: https://pkg.go.dev/github.com/cenkalti/backoff/v4?tab=doc#pkg-examples
...@@ -7,7 +7,7 @@ import ( ...@@ -7,7 +7,7 @@ import (
// BackOffContext is a backoff policy that stops retrying after the context // BackOffContext is a backoff policy that stops retrying after the context
// is canceled. // is canceled.
type BackOffContext interface { type BackOffContext interface { // nolint: golint
BackOff BackOff
Context() context.Context Context() context.Context
} }
...@@ -20,7 +20,7 @@ type backOffContext struct { ...@@ -20,7 +20,7 @@ type backOffContext struct {
// WithContext returns a BackOffContext with context ctx // WithContext returns a BackOffContext with context ctx
// //
// ctx must not be nil // ctx must not be nil
func WithContext(b BackOff, ctx context.Context) BackOffContext { func WithContext(b BackOff, ctx context.Context) BackOffContext { // nolint: golint
if ctx == nil { if ctx == nil {
panic("nil context") panic("nil context")
} }
...@@ -38,11 +38,14 @@ func WithContext(b BackOff, ctx context.Context) BackOffContext { ...@@ -38,11 +38,14 @@ func WithContext(b BackOff, ctx context.Context) BackOffContext {
} }
} }
func ensureContext(b BackOff) BackOffContext { func getContext(b BackOff) context.Context {
if cb, ok := b.(BackOffContext); ok { if cb, ok := b.(BackOffContext); ok {
return cb return cb.Context()
} }
return WithContext(b, context.Background()) if tb, ok := b.(*backOffTries); ok {
return getContext(tb.delegate)
}
return context.Background()
} }
func (b *backOffContext) Context() context.Context { func (b *backOffContext) Context() context.Context {
...@@ -54,10 +57,6 @@ func (b *backOffContext) NextBackOff() time.Duration { ...@@ -54,10 +57,6 @@ func (b *backOffContext) NextBackOff() time.Duration {
case <-b.ctx.Done(): case <-b.ctx.Done():
return Stop return Stop
default: default:
return b.BackOff.NextBackOff()
} }
next := b.BackOff.NextBackOff()
if deadline, ok := b.ctx.Deadline(); ok && deadline.Sub(time.Now()) < next {
return Stop
}
return next
} }
...@@ -56,9 +56,10 @@ type ExponentialBackOff struct { ...@@ -56,9 +56,10 @@ type ExponentialBackOff struct {
RandomizationFactor float64 RandomizationFactor float64
Multiplier float64 Multiplier float64
MaxInterval time.Duration MaxInterval time.Duration
// After MaxElapsedTime the ExponentialBackOff stops. // After MaxElapsedTime the ExponentialBackOff returns Stop.
// It never stops if MaxElapsedTime == 0. // It never stops if MaxElapsedTime == 0.
MaxElapsedTime time.Duration MaxElapsedTime time.Duration
Stop time.Duration
Clock Clock Clock Clock
currentInterval time.Duration currentInterval time.Duration
...@@ -87,6 +88,7 @@ func NewExponentialBackOff() *ExponentialBackOff { ...@@ -87,6 +88,7 @@ func NewExponentialBackOff() *ExponentialBackOff {
Multiplier: DefaultMultiplier, Multiplier: DefaultMultiplier,
MaxInterval: DefaultMaxInterval, MaxInterval: DefaultMaxInterval,
MaxElapsedTime: DefaultMaxElapsedTime, MaxElapsedTime: DefaultMaxElapsedTime,
Stop: Stop,
Clock: SystemClock, Clock: SystemClock,
} }
b.Reset() b.Reset()
...@@ -103,20 +105,23 @@ func (t systemClock) Now() time.Time { ...@@ -103,20 +105,23 @@ func (t systemClock) Now() time.Time {
var SystemClock = systemClock{} var SystemClock = systemClock{}
// Reset the interval back to the initial retry interval and restarts the timer. // Reset the interval back to the initial retry interval and restarts the timer.
// Reset must be called before using b.
func (b *ExponentialBackOff) Reset() { func (b *ExponentialBackOff) Reset() {
b.currentInterval = b.InitialInterval b.currentInterval = b.InitialInterval
b.startTime = b.Clock.Now() b.startTime = b.Clock.Now()
} }
// NextBackOff calculates the next backoff interval using the formula: // NextBackOff calculates the next backoff interval using the formula:
// Randomized interval = RetryInterval +/- (RandomizationFactor * RetryInterval) // Randomized interval = RetryInterval * (1 ± RandomizationFactor)
func (b *ExponentialBackOff) NextBackOff() time.Duration { func (b *ExponentialBackOff) NextBackOff() time.Duration {
// Make sure we have not gone over the maximum elapsed time. // Make sure we have not gone over the maximum elapsed time.
if b.MaxElapsedTime != 0 && b.GetElapsedTime() > b.MaxElapsedTime { elapsed := b.GetElapsedTime()
return Stop next := getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval)
b.incrementCurrentInterval()
if b.MaxElapsedTime != 0 && elapsed+next > b.MaxElapsedTime {
return b.Stop
} }
defer b.incrementCurrentInterval() return next
return getRandomValueFromInterval(b.RandomizationFactor, rand.Float64(), b.currentInterval)
} }
// GetElapsedTime returns the elapsed time since an ExponentialBackOff instance // GetElapsedTime returns the elapsed time since an ExponentialBackOff instance
...@@ -140,8 +145,11 @@ func (b *ExponentialBackOff) incrementCurrentInterval() { ...@@ -140,8 +145,11 @@ func (b *ExponentialBackOff) incrementCurrentInterval() {
} }
// Returns a random value from the following interval: // Returns a random value from the following interval:
// [randomizationFactor * currentInterval, randomizationFactor * currentInterval]. // [currentInterval - randomizationFactor * currentInterval, currentInterval + randomizationFactor * currentInterval].
func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration { func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration {
if randomizationFactor == 0 {
return currentInterval // make sure no randomness is used when randomizationFactor is 0.
}
var delta = randomizationFactor * float64(currentInterval) var delta = randomizationFactor * float64(currentInterval)
var minInterval = float64(currentInterval) - delta var minInterval = float64(currentInterval) - delta
var maxInterval = float64(currentInterval) + delta var maxInterval = float64(currentInterval) + delta
......
package backoff
import "time"
type Timer interface {
Start(duration time.Duration)
Stop()
C() <-chan time.Time
}
// defaultTimer implements Timer interface using time.Timer
type defaultTimer struct {
timer *time.Timer
}
// C returns the timers channel which receives the current time when the timer fires.
func (t *defaultTimer) C() <-chan time.Time {
return t.timer.C
}
// Start starts the timer to fire after the given duration
func (t *defaultTimer) Start(duration time.Duration) {
if t.timer == nil {
t.timer = time.NewTimer(duration)
} else {
t.timer.Reset(duration)
}
}
// Stop is called when the timer is not used anymore and resources may be freed.
func (t *defaultTimer) Stop() {
if t.timer != nil {
t.timer.Stop()
}
}
...@@ -20,6 +20,9 @@ type backOffTries struct { ...@@ -20,6 +20,9 @@ type backOffTries struct {
} }
func (b *backOffTries) NextBackOff() time.Duration { func (b *backOffTries) NextBackOff() time.Duration {
if b.maxTries == 0 {
return Stop
}
if b.maxTries > 0 { if b.maxTries > 0 {
if b.maxTries <= b.numTries { if b.maxTries <= b.numTries {
return Stop return Stop
......
language: go
go:
- "1.x"
- master
env:
- TAGS=""
- TAGS="-tags purego"
script: go test $TAGS -v ./...
This diff is collapsed.