backoff: set default values on BackoffConfig
Because most of the fields on `BackoffConfig` are unexported, correctly using the config requires copying from the default. This sets the defaults appropriately and falls back to a default if MaxDelay is negative or zero. Tests are added to ensure that the backoff is set correctly in common use cases. Signedroff-by: Stephen J Day <stephen.day@docker.com> Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
@ -46,6 +46,15 @@ type BackoffConfig struct {
|
|||||||
jitter float64
|
jitter float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bc *BackoffConfig) setDefaults() {
|
||||||
|
md := bc.MaxDelay
|
||||||
|
*bc = *DefaultBackoffConfig
|
||||||
|
|
||||||
|
if md > 0 {
|
||||||
|
bc.MaxDelay = md
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (bc *BackoffConfig) backoff(retries int) (t time.Duration) {
|
func (bc *BackoffConfig) backoff(retries int) (t time.Duration) {
|
||||||
if retries == 0 {
|
if retries == 0 {
|
||||||
return bc.baseDelay
|
return bc.baseDelay
|
||||||
|
11
backoff_test.go
Normal file
11
backoff_test.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package grpc
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestBackoffConfigDefaults(t *testing.T) {
|
||||||
|
b := BackoffConfig{}
|
||||||
|
b.setDefaults()
|
||||||
|
if b != *DefaultBackoffConfig {
|
||||||
|
t.Fatalf("expected BackoffConfig to pickup default parameters: %v != %v", b, *DefaultBackoffConfig)
|
||||||
|
}
|
||||||
|
}
|
@ -115,9 +115,21 @@ func WithPicker(p Picker) DialOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithBackoffMaxDelay configures the dialer to use the provided maximum delay
|
||||||
|
// when backing off after failed connection attempts.
|
||||||
|
func WithBackoffMaxDelay(md time.Duration) DialOption {
|
||||||
|
return WithBackoffConfig(&BackoffConfig{MaxDelay: md})
|
||||||
|
}
|
||||||
|
|
||||||
// WithBackoffConfig configures the dialer to use the provided backoff
|
// WithBackoffConfig configures the dialer to use the provided backoff
|
||||||
// parameters after connection failures.
|
// parameters after connection failures.
|
||||||
|
//
|
||||||
|
// Use WithBackoffMaxDelay until more parameters on BackoffConfig are opened up
|
||||||
|
// for use.
|
||||||
func WithBackoffConfig(b *BackoffConfig) DialOption {
|
func WithBackoffConfig(b *BackoffConfig) DialOption {
|
||||||
|
// Set defaults to ensure that provided BackoffConfig is valid and
|
||||||
|
// unexported fields get default values.
|
||||||
|
b.setDefaults()
|
||||||
return withBackoff(b)
|
return withBackoff(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,3 +80,42 @@ func TestCredentialsMisuse(t *testing.T) {
|
|||||||
t.Fatalf("Dial(_, _) = _, %v, want _, %v", err, ErrCredentialsMisuse)
|
t.Fatalf("Dial(_, _) = _, %v, want _, %v", err, ErrCredentialsMisuse)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWithBackoffConfigDefault(t *testing.T) {
|
||||||
|
testBackoffConfigSet(t, DefaultBackoffConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithBackoffConfig(t *testing.T) {
|
||||||
|
b := BackoffConfig{MaxDelay: DefaultBackoffConfig.MaxDelay / 2}
|
||||||
|
expected := b
|
||||||
|
expected.setDefaults() // defaults should be set
|
||||||
|
testBackoffConfigSet(t, &expected, WithBackoffConfig(&b))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWithBackoffMaxDelay(t *testing.T) {
|
||||||
|
md := DefaultBackoffConfig.MaxDelay / 2
|
||||||
|
expected := BackoffConfig{MaxDelay: md}
|
||||||
|
expected.setDefaults()
|
||||||
|
testBackoffConfigSet(t, &expected, WithBackoffMaxDelay(md))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testBackoffConfigSet(t *testing.T, expected *BackoffConfig, opts ...DialOption) {
|
||||||
|
opts = append(opts, WithInsecure())
|
||||||
|
conn, err := Dial("foo:80", opts...)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error dialing connection: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if conn.dopts.bs == nil {
|
||||||
|
t.Fatalf("backoff config not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, ok := conn.dopts.bs.(*BackoffConfig)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("unexpected type of backoff config: %v", conn.dopts.bs)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *actual != *expected {
|
||||||
|
t.Fatalf("unexpected backoff config on connection: %v, want %v", actual, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user