PLT-3753 Added Segment analytics (#3972)
Этот коммит содержится в:
80
vendor/github.com/segmentio/backo-go/README.md
сгенерированный
поставляемый
Обычный файл
80
vendor/github.com/segmentio/backo-go/README.md
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,80 @@
|
||||
Backo [](http://godoc.org/github.com/segmentio/backo-go)
|
||||
-----
|
||||
|
||||
Exponential backoff for Go (Go port of segmentio/backo).
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
```go
|
||||
import "github.com/segmentio/backo-go"
|
||||
|
||||
// Create a Backo instance.
|
||||
backo := backo.NewBacko(milliseconds(100), 2, 1, milliseconds(10*1000))
|
||||
// OR with defaults.
|
||||
backo := backo.DefaultBacko()
|
||||
|
||||
// Use the ticker API.
|
||||
ticker := b.NewTicker()
|
||||
for {
|
||||
timeout := time.After(5 * time.Minute)
|
||||
select {
|
||||
case <-ticker.C:
|
||||
fmt.Println("ticked")
|
||||
case <- timeout:
|
||||
fmt.Println("timed out")
|
||||
}
|
||||
}
|
||||
|
||||
// Or simply work with backoff intervals directly.
|
||||
for i := 0; i < n; i++ {
|
||||
// Sleep the current goroutine.
|
||||
backo.Sleep(i)
|
||||
// Retrieve the duration manually.
|
||||
duration := backo.Duration(i)
|
||||
}
|
||||
```
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
```
|
||||
WWWWWW||WWWWWW
|
||||
W W W||W W W
|
||||
||
|
||||
( OO )__________
|
||||
/ | \
|
||||
/o o| MIT \
|
||||
\___/||_||__||_|| *
|
||||
|| || || ||
|
||||
_||_|| _||_||
|
||||
(__|__|(__|__|
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Segment, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
```
|
||||
|
||||
|
||||
|
||||
[1]: http://github.com/segmentio/backo-java
|
||||
[2]: http://repository.sonatype.org/service/local/artifact/maven/redirect?r=central-proxy&g=com.segment.backo&a=backo&v=LATEST
|
||||
83
vendor/github.com/segmentio/backo-go/backo.go
сгенерированный
поставляемый
Обычный файл
83
vendor/github.com/segmentio/backo-go/backo.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,83 @@
|
||||
package backo
|
||||
|
||||
import (
|
||||
"math"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Backo struct {
|
||||
base time.Duration
|
||||
factor uint8
|
||||
jitter float64
|
||||
cap time.Duration
|
||||
}
|
||||
|
||||
// Creates a backo instance with the given parameters
|
||||
func NewBacko(base time.Duration, factor uint8, jitter float64, cap time.Duration) *Backo {
|
||||
return &Backo{base, factor, jitter, cap}
|
||||
}
|
||||
|
||||
// Creates a backo instance with the following defaults:
|
||||
// base: 100 milliseconds
|
||||
// factor: 2
|
||||
// jitter: 0
|
||||
// cap: 10 seconds
|
||||
func DefaultBacko() *Backo {
|
||||
return NewBacko(time.Millisecond*100, 2, 0, time.Second*10)
|
||||
}
|
||||
|
||||
// Duration returns the backoff interval for the given attempt.
|
||||
func (backo *Backo) Duration(attempt int) time.Duration {
|
||||
duration := float64(backo.base) * math.Pow(float64(backo.factor), float64(attempt))
|
||||
|
||||
if backo.jitter != 0 {
|
||||
random := rand.Float64()
|
||||
deviation := math.Floor(random * backo.jitter * duration)
|
||||
if (int(math.Floor(random*10)) & 1) == 0 {
|
||||
duration = duration - deviation
|
||||
} else {
|
||||
duration = duration + deviation
|
||||
}
|
||||
}
|
||||
|
||||
duration = math.Min(float64(duration), float64(backo.cap))
|
||||
return time.Duration(duration)
|
||||
}
|
||||
|
||||
// Sleep pauses the current goroutine for the backoff interval for the given attempt.
|
||||
func (backo *Backo) Sleep(attempt int) {
|
||||
duration := backo.Duration(attempt)
|
||||
time.Sleep(duration)
|
||||
}
|
||||
|
||||
type Ticker struct {
|
||||
done chan struct{}
|
||||
C <-chan time.Time
|
||||
}
|
||||
|
||||
func (b *Backo) NewTicker() *Ticker {
|
||||
c := make(chan time.Time, 1)
|
||||
ticker := &Ticker{
|
||||
done: make(chan struct{}, 1),
|
||||
C: c,
|
||||
}
|
||||
|
||||
go func() {
|
||||
for i := 0; ; i++ {
|
||||
select {
|
||||
case t := <-time.After(b.Duration(i)):
|
||||
c <- t
|
||||
case <-ticker.done:
|
||||
close(c)
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return ticker
|
||||
}
|
||||
|
||||
func (t *Ticker) Stop() {
|
||||
t.done <- struct{}{}
|
||||
}
|
||||
77
vendor/github.com/segmentio/backo-go/backo_test.go
сгенерированный
поставляемый
Обычный файл
77
vendor/github.com/segmentio/backo-go/backo_test.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,77 @@
|
||||
package backo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/bmizerany/assert"
|
||||
)
|
||||
|
||||
// Tests default backo behaviour.
|
||||
func TestDefaults(t *testing.T) {
|
||||
backo := DefaultBacko()
|
||||
|
||||
assert.Equal(t, milliseconds(100), backo.Duration(0))
|
||||
assert.Equal(t, milliseconds(200), backo.Duration(1))
|
||||
assert.Equal(t, milliseconds(400), backo.Duration(2))
|
||||
assert.Equal(t, milliseconds(800), backo.Duration(3))
|
||||
}
|
||||
|
||||
// Tests backo does not exceed cap.
|
||||
func TestCap(t *testing.T) {
|
||||
backo := NewBacko(milliseconds(100), 2, 0, milliseconds(600))
|
||||
|
||||
assert.Equal(t, milliseconds(100), backo.Duration(0))
|
||||
assert.Equal(t, milliseconds(200), backo.Duration(1))
|
||||
assert.Equal(t, milliseconds(400), backo.Duration(2))
|
||||
assert.Equal(t, milliseconds(600), backo.Duration(3))
|
||||
}
|
||||
|
||||
// Tests that jitter adds randomness.
|
||||
func TestJitter(t *testing.T) {
|
||||
defaultBacko := NewBacko(milliseconds(100), 2, 1, milliseconds(10*1000))
|
||||
jitterBacko := NewBacko(milliseconds(100), 2, 1, milliseconds(10*1000))
|
||||
|
||||
// TODO: Check jittered durations are within a range.
|
||||
assert.NotEqual(t, jitterBacko.Duration(0), defaultBacko.Duration(0))
|
||||
assert.NotEqual(t, jitterBacko.Duration(1), defaultBacko.Duration(1))
|
||||
assert.NotEqual(t, jitterBacko.Duration(2), defaultBacko.Duration(2))
|
||||
assert.NotEqual(t, jitterBacko.Duration(3), defaultBacko.Duration(3))
|
||||
}
|
||||
|
||||
func ExampleBacko_BackoffDefault() {
|
||||
b := DefaultBacko()
|
||||
ticker := b.NewTicker()
|
||||
|
||||
for i := 0; i < 6; i++ {
|
||||
start := time.Now()
|
||||
select {
|
||||
case t := <-ticker.C:
|
||||
fmt.Println(nearest10Millis(t.Sub(start)))
|
||||
}
|
||||
}
|
||||
|
||||
ticker.Stop()
|
||||
|
||||
// Output:
|
||||
// 100
|
||||
// 200
|
||||
// 400
|
||||
// 800
|
||||
// 1600
|
||||
// 3200
|
||||
}
|
||||
|
||||
func nearest10Millis(d time.Duration) float64 {
|
||||
// Typically d is something like 11 or 21, so do some magic to round the
|
||||
// durations to the nearest 10. We divide d by 10, floor it, and multiply it
|
||||
// by 10 again.
|
||||
return math.Floor(float64(d/time.Millisecond/10) * 10)
|
||||
}
|
||||
|
||||
// Returns the given milliseconds as time.Duration
|
||||
func milliseconds(ms int64) time.Duration {
|
||||
return time.Duration(ms * 1000 * 1000)
|
||||
}
|
||||
Ссылка в новой задаче
Block a user