Moved to google.golang.org/genproto/googleapis/api/annotations

Fixes #52
This commit is contained in:
Valerio Gheri
2017-03-31 18:01:58 +02:00
parent 024c5a4e4e
commit c40779224f
2037 changed files with 831329 additions and 1854 deletions

15
vendor/github.com/go-kit/kit/sd/lb/balancer.go generated vendored Normal file
View File

@@ -0,0 +1,15 @@
package lb
import (
"errors"
"github.com/go-kit/kit/endpoint"
)
// Balancer yields endpoints according to some heuristic.
type Balancer interface {
Endpoint() (endpoint.Endpoint, error)
}
// ErrNoEndpoints is returned when no qualifying endpoints are available.
var ErrNoEndpoints = errors.New("no endpoints available")

4
vendor/github.com/go-kit/kit/sd/lb/doc.go generated vendored Normal file
View File

@@ -0,0 +1,4 @@
// Package lb implements the client-side load balancer pattern. When combined
// with a service discovery system of record, it enables a more decentralized
// architecture, removing the need for separate load balancers like HAProxy.
package lb

32
vendor/github.com/go-kit/kit/sd/lb/random.go generated vendored Normal file
View File

@@ -0,0 +1,32 @@
package lb
import (
"math/rand"
"github.com/go-kit/kit/endpoint"
"github.com/go-kit/kit/sd"
)
// NewRandom returns a load balancer that selects services randomly.
func NewRandom(s sd.Subscriber, seed int64) Balancer {
return &random{
s: s,
r: rand.New(rand.NewSource(seed)),
}
}
type random struct {
s sd.Subscriber
r *rand.Rand
}
func (r *random) Endpoint() (endpoint.Endpoint, error) {
endpoints, err := r.s.Endpoints()
if err != nil {
return nil, err
}
if len(endpoints) <= 0 {
return nil, ErrNoEndpoints
}
return endpoints[r.r.Intn(len(endpoints))], nil
}

52
vendor/github.com/go-kit/kit/sd/lb/random_test.go generated vendored Normal file
View File

@@ -0,0 +1,52 @@
package lb
import (
"context"
"math"
"testing"
"github.com/go-kit/kit/endpoint"
"github.com/go-kit/kit/sd"
)
func TestRandom(t *testing.T) {
var (
n = 7
endpoints = make([]endpoint.Endpoint, n)
counts = make([]int, n)
seed = int64(12345)
iterations = 1000000
want = iterations / n
tolerance = want / 100 // 1%
)
for i := 0; i < n; i++ {
i0 := i
endpoints[i] = func(context.Context, interface{}) (interface{}, error) { counts[i0]++; return struct{}{}, nil }
}
subscriber := sd.FixedSubscriber(endpoints)
balancer := NewRandom(subscriber, seed)
for i := 0; i < iterations; i++ {
endpoint, _ := balancer.Endpoint()
endpoint(context.Background(), struct{}{})
}
for i, have := range counts {
delta := int(math.Abs(float64(want - have)))
if delta > tolerance {
t.Errorf("%d: want %d, have %d, delta %d > %d tolerance", i, want, have, delta, tolerance)
}
}
}
func TestRandomNoEndpoints(t *testing.T) {
subscriber := sd.FixedSubscriber{}
balancer := NewRandom(subscriber, 1415926)
_, err := balancer.Endpoint()
if want, have := ErrNoEndpoints, err; want != have {
t.Errorf("want %v, have %v", want, have)
}
}

117
vendor/github.com/go-kit/kit/sd/lb/retry.go generated vendored Normal file
View File

@@ -0,0 +1,117 @@
package lb
import (
"context"
"fmt"
"strings"
"time"
"github.com/go-kit/kit/endpoint"
)
// RetryError is an error wrapper that is used by the retry mechanism. All
// errors returned by the retry mechanism via its endpoint will be RetryErrors.
type RetryError struct {
RawErrors []error // all errors encountered from endpoints directly
Final error // the final, terminating error
}
func (e RetryError) Error() string {
var suffix string
if len(e.RawErrors) > 1 {
a := make([]string, len(e.RawErrors)-1)
for i := 0; i < len(e.RawErrors)-1; i++ { // last one is Final
a[i] = e.RawErrors[i].Error()
}
suffix = fmt.Sprintf(" (previously: %s)", strings.Join(a, "; "))
}
return fmt.Sprintf("%v%s", e.Final, suffix)
}
// Callback is a function that is given the current attempt count and the error
// received from the underlying endpoint. It should return whether the Retry
// function should continue trying to get a working endpoint, and a custom error
// if desired. The error message may be nil, but a true/false is always
// expected. In all cases, if the replacement error is supplied, the received
// error will be replaced in the calling context.
type Callback func(n int, received error) (keepTrying bool, replacement error)
// Retry wraps a service load balancer and returns an endpoint oriented load
// balancer for the specified service method. Requests to the endpoint will be
// automatically load balanced via the load balancer. Requests that return
// errors will be retried until they succeed, up to max times, or until the
// timeout is elapsed, whichever comes first.
func Retry(max int, timeout time.Duration, b Balancer) endpoint.Endpoint {
return RetryWithCallback(timeout, b, maxRetries(max))
}
func maxRetries(max int) Callback {
return func(n int, err error) (keepTrying bool, replacement error) {
return n < max, nil
}
}
func alwaysRetry(int, error) (keepTrying bool, replacement error) {
return true, nil
}
// RetryWithCallback wraps a service load balancer and returns an endpoint
// oriented load balancer for the specified service method. Requests to the
// endpoint will be automatically load balanced via the load balancer. Requests
// that return errors will be retried until they succeed, up to max times, until
// the callback returns false, or until the timeout is elapsed, whichever comes
// first.
func RetryWithCallback(timeout time.Duration, b Balancer, cb Callback) endpoint.Endpoint {
if cb == nil {
cb = alwaysRetry
}
if b == nil {
panic("nil Balancer")
}
return func(ctx context.Context, request interface{}) (response interface{}, err error) {
var (
newctx, cancel = context.WithTimeout(ctx, timeout)
responses = make(chan interface{}, 1)
errs = make(chan error, 1)
final RetryError
)
defer cancel()
for i := 1; ; i++ {
go func() {
e, err := b.Endpoint()
if err != nil {
errs <- err
return
}
response, err := e(newctx, request)
if err != nil {
errs <- err
return
}
responses <- response
}()
select {
case <-newctx.Done():
return nil, newctx.Err()
case response := <-responses:
return response, nil
case err := <-errs:
final.RawErrors = append(final.RawErrors, err)
keepTrying, replacement := cb(i, err)
if replacement != nil {
err = replacement
}
if !keepTrying {
final.Final = err
return nil, final
}
continue
}
}
}
}

141
vendor/github.com/go-kit/kit/sd/lb/retry_test.go generated vendored Normal file
View File

@@ -0,0 +1,141 @@
package lb_test
import (
"context"
"errors"
"testing"
"time"
"github.com/go-kit/kit/endpoint"
"github.com/go-kit/kit/sd"
"github.com/go-kit/kit/sd/lb"
)
func TestRetryMaxTotalFail(t *testing.T) {
var (
endpoints = sd.FixedSubscriber{} // no endpoints
rr = lb.NewRoundRobin(endpoints)
retry = lb.Retry(999, time.Second, rr) // lots of retries
ctx = context.Background()
)
if _, err := retry(ctx, struct{}{}); err == nil {
t.Errorf("expected error, got none") // should fail
}
}
func TestRetryMaxPartialFail(t *testing.T) {
var (
endpoints = []endpoint.Endpoint{
func(context.Context, interface{}) (interface{}, error) { return nil, errors.New("error one") },
func(context.Context, interface{}) (interface{}, error) { return nil, errors.New("error two") },
func(context.Context, interface{}) (interface{}, error) { return struct{}{}, nil /* OK */ },
}
subscriber = sd.FixedSubscriber{
0: endpoints[0],
1: endpoints[1],
2: endpoints[2],
}
retries = len(endpoints) - 1 // not quite enough retries
rr = lb.NewRoundRobin(subscriber)
ctx = context.Background()
)
if _, err := lb.Retry(retries, time.Second, rr)(ctx, struct{}{}); err == nil {
t.Errorf("expected error two, got none")
}
}
func TestRetryMaxSuccess(t *testing.T) {
var (
endpoints = []endpoint.Endpoint{
func(context.Context, interface{}) (interface{}, error) { return nil, errors.New("error one") },
func(context.Context, interface{}) (interface{}, error) { return nil, errors.New("error two") },
func(context.Context, interface{}) (interface{}, error) { return struct{}{}, nil /* OK */ },
}
subscriber = sd.FixedSubscriber{
0: endpoints[0],
1: endpoints[1],
2: endpoints[2],
}
retries = len(endpoints) // exactly enough retries
rr = lb.NewRoundRobin(subscriber)
ctx = context.Background()
)
if _, err := lb.Retry(retries, time.Second, rr)(ctx, struct{}{}); err != nil {
t.Error(err)
}
}
func TestRetryTimeout(t *testing.T) {
var (
step = make(chan struct{})
e = func(context.Context, interface{}) (interface{}, error) { <-step; return struct{}{}, nil }
timeout = time.Millisecond
retry = lb.Retry(999, timeout, lb.NewRoundRobin(sd.FixedSubscriber{0: e}))
errs = make(chan error, 1)
invoke = func() { _, err := retry(context.Background(), struct{}{}); errs <- err }
)
go func() { step <- struct{}{} }() // queue up a flush of the endpoint
invoke() // invoke the endpoint and trigger the flush
if err := <-errs; err != nil { // that should succeed
t.Error(err)
}
go func() { time.Sleep(10 * timeout); step <- struct{}{} }() // a delayed flush
invoke() // invoke the endpoint
if err := <-errs; err != context.DeadlineExceeded { // that should not succeed
t.Errorf("wanted %v, got none", context.DeadlineExceeded)
}
}
func TestAbortEarlyCustomMessage(t *testing.T) {
var (
myErr = errors.New("aborting early")
cb = func(int, error) (bool, error) { return false, myErr }
endpoints = sd.FixedSubscriber{} // no endpoints
rr = lb.NewRoundRobin(endpoints)
retry = lb.RetryWithCallback(time.Second, rr, cb) // lots of retries
ctx = context.Background()
)
_, err := retry(ctx, struct{}{})
if want, have := myErr, err.(lb.RetryError).Final; want != have {
t.Errorf("want %v, have %v", want, have)
}
}
func TestErrorPassedUnchangedToCallback(t *testing.T) {
var (
myErr = errors.New("my custom error")
cb = func(_ int, err error) (bool, error) {
if want, have := myErr, err; want != have {
t.Errorf("want %v, have %v", want, have)
}
return false, nil
}
endpoint = func(ctx context.Context, request interface{}) (interface{}, error) {
return nil, myErr
}
endpoints = sd.FixedSubscriber{endpoint} // no endpoints
rr = lb.NewRoundRobin(endpoints)
retry = lb.RetryWithCallback(time.Second, rr, cb) // lots of retries
ctx = context.Background()
)
_, err := retry(ctx, struct{}{})
if want, have := myErr, err.(lb.RetryError).Final; want != have {
t.Errorf("want %v, have %v", want, have)
}
}
func TestHandleNilCallback(t *testing.T) {
var (
subscriber = sd.FixedSubscriber{
func(context.Context, interface{}) (interface{}, error) { return struct{}{}, nil /* OK */ },
}
rr = lb.NewRoundRobin(subscriber)
ctx = context.Background()
)
retry := lb.RetryWithCallback(time.Second, rr, nil)
if _, err := retry(ctx, struct{}{}); err != nil {
t.Error(err)
}
}

34
vendor/github.com/go-kit/kit/sd/lb/round_robin.go generated vendored Normal file
View File

@@ -0,0 +1,34 @@
package lb
import (
"sync/atomic"
"github.com/go-kit/kit/endpoint"
"github.com/go-kit/kit/sd"
)
// NewRoundRobin returns a load balancer that returns services in sequence.
func NewRoundRobin(s sd.Subscriber) Balancer {
return &roundRobin{
s: s,
c: 0,
}
}
type roundRobin struct {
s sd.Subscriber
c uint64
}
func (rr *roundRobin) Endpoint() (endpoint.Endpoint, error) {
endpoints, err := rr.s.Endpoints()
if err != nil {
return nil, err
}
if len(endpoints) <= 0 {
return nil, ErrNoEndpoints
}
old := atomic.AddUint64(&rr.c, 1) - 1
idx := old % uint64(len(endpoints))
return endpoints[idx], nil
}

95
vendor/github.com/go-kit/kit/sd/lb/round_robin_test.go generated vendored Normal file
View File

@@ -0,0 +1,95 @@
package lb
import (
"context"
"reflect"
"sync"
"sync/atomic"
"testing"
"time"
"github.com/go-kit/kit/endpoint"
"github.com/go-kit/kit/sd"
)
func TestRoundRobin(t *testing.T) {
var (
counts = []int{0, 0, 0}
endpoints = []endpoint.Endpoint{
func(context.Context, interface{}) (interface{}, error) { counts[0]++; return struct{}{}, nil },
func(context.Context, interface{}) (interface{}, error) { counts[1]++; return struct{}{}, nil },
func(context.Context, interface{}) (interface{}, error) { counts[2]++; return struct{}{}, nil },
}
)
subscriber := sd.FixedSubscriber(endpoints)
balancer := NewRoundRobin(subscriber)
for i, want := range [][]int{
{1, 0, 0},
{1, 1, 0},
{1, 1, 1},
{2, 1, 1},
{2, 2, 1},
{2, 2, 2},
{3, 2, 2},
} {
endpoint, err := balancer.Endpoint()
if err != nil {
t.Fatal(err)
}
endpoint(context.Background(), struct{}{})
if have := counts; !reflect.DeepEqual(want, have) {
t.Fatalf("%d: want %v, have %v", i, want, have)
}
}
}
func TestRoundRobinNoEndpoints(t *testing.T) {
subscriber := sd.FixedSubscriber{}
balancer := NewRoundRobin(subscriber)
_, err := balancer.Endpoint()
if want, have := ErrNoEndpoints, err; want != have {
t.Errorf("want %v, have %v", want, have)
}
}
func TestRoundRobinNoRace(t *testing.T) {
balancer := NewRoundRobin(sd.FixedSubscriber([]endpoint.Endpoint{
endpoint.Nop,
endpoint.Nop,
endpoint.Nop,
endpoint.Nop,
endpoint.Nop,
}))
var (
n = 100
done = make(chan struct{})
wg sync.WaitGroup
count uint64
)
wg.Add(n)
for i := 0; i < n; i++ {
go func() {
defer wg.Done()
for {
select {
case <-done:
return
default:
_, _ = balancer.Endpoint()
atomic.AddUint64(&count, 1)
}
}
}()
}
time.Sleep(time.Second)
close(done)
wg.Wait()
t.Logf("made %d calls", atomic.LoadUint64(&count))
}