To enforce immutability of the `DefaultBackoffConfig`, we've made it a
concrete value. While fields can still be set directly on the value,
taking a copy will not incidentally pull a reference to the variable.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
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>
The backoff function and parameters have been pulled up into an
interface `backoffStrategy`. The default parameters are now part of a
package variable `DefaultBackoffConfig`. The strategy is then plumbed
through `dialOptions`. As a result of this PR, the
maximum backoff delay can now be set using the `WithBackoffConfig` dial
option.
While the addition of strategy may seem premature, this allows one to
simply export `BackoffStrategy` and `WithBackoff` to allow arbirarily
configurable backoff strategies.
Signed-off-by: Stephen J Day <stephen.day@docker.com>
Also changes the receivers to pointers because:
- Implementing an interface using value receivers causes both pointers
and values to implement that interface; implementing an interface using
pointer receivers causes only pointers to implement the interface,
thereby providing better type safety.
- Wrapping any value other than an empty struct in an interface causes
the value to be heap-allocated; no additional allocations are therefore
caused by this change.