|
|
@@ -37,6 +37,10 @@ var (
|
|
|
ErrClusterUnavailable = errors.New("client: etcd cluster is unavailable or misconfigured")
|
|
|
ErrNoLeaderEndpoint = errors.New("client: no leader endpoint available")
|
|
|
errTooManyRedirectChecks = errors.New("client: too many redirect checks")
|
|
|
+
|
|
|
+ // oneShotCtxValue is set on a context using WithValue(&oneShotValue) so
|
|
|
+ // that Do() will not retry a request
|
|
|
+ oneShotCtxValue interface{}
|
|
|
)
|
|
|
|
|
|
var DefaultRequestTimeout = 5 * time.Second
|
|
|
@@ -335,6 +339,7 @@ func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Respo
|
|
|
var body []byte
|
|
|
var err error
|
|
|
cerr := &ClusterError{}
|
|
|
+ isOneShot := ctx.Value(&oneShotCtxValue) != nil
|
|
|
|
|
|
for i := pinned; i < leps+pinned; i++ {
|
|
|
k := i % leps
|
|
|
@@ -348,6 +353,9 @@ func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Respo
|
|
|
if err == context.Canceled || err == context.DeadlineExceeded {
|
|
|
return nil, nil, err
|
|
|
}
|
|
|
+ if isOneShot {
|
|
|
+ return nil, nil, err
|
|
|
+ }
|
|
|
continue
|
|
|
}
|
|
|
if resp.StatusCode/100 == 5 {
|
|
|
@@ -358,6 +366,9 @@ func (c *httpClusterClient) Do(ctx context.Context, act httpAction) (*http.Respo
|
|
|
default:
|
|
|
cerr.Errors = append(cerr.Errors, fmt.Errorf("client: etcd member %s returns server error [%s]", eps[k].String(), http.StatusText(resp.StatusCode)))
|
|
|
}
|
|
|
+ if isOneShot {
|
|
|
+ return nil, nil, cerr.Errors[0]
|
|
|
+ }
|
|
|
continue
|
|
|
}
|
|
|
if k != pinned {
|