From bbb7fb5a46fe84362160e8fb0f7578fdd780d6e2 Mon Sep 17 00:00:00 2001 From: Gyu-Ho Lee Date: Thu, 21 Jan 2016 18:45:15 -0800 Subject: [PATCH] client: do not timeout when wait is true Current V2 watch waits by encoding URL with wait=true. When a client sets 'no-sync', it requests directly to proxy and the proxy redirects it by cloning the request object, which leads to cancel the original request when it times out and the cloned request gets closed prematurely. This fixes coreos#3894 by querying the original client request in order to not use context timeout when 'wait=true'. --- client/client.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/client/client.go b/client/client.go index 728910340..9d7735cdf 100644 --- a/client/client.go +++ b/client/client.go @@ -24,6 +24,7 @@ import ( "net/url" "reflect" "sort" + "strconv" "sync" "time" @@ -123,6 +124,8 @@ type Config struct { // watch start. But if server is behind some kind of proxy, the response // header may be cached at proxy, and Client cannot rely on this behavior. // + // Especially, wait request will ignore this timeout. + // // One API call may send multiple requests to different etcd servers until it // succeeds. Use context of the API to specify the overall timeout. // @@ -442,9 +445,21 @@ func (c *simpleHTTPClient) Do(ctx context.Context, act httpAction) (*http.Respon return nil, nil, err } + isWait := false + if req != nil && req.URL != nil { + ws := req.URL.Query().Get("wait") + if len(ws) != 0 { + var err error + isWait, err = strconv.ParseBool(ws) + if err != nil { + return nil, nil, fmt.Errorf("wrong wait value %s (%v for %+v)", ws, err, req) + } + } + } + var hctx context.Context var hcancel context.CancelFunc - if c.headerTimeout > 0 { + if !isWait && c.headerTimeout > 0 { hctx, hcancel = context.WithTimeout(ctx, c.headerTimeout) } else { hctx, hcancel = context.WithCancel(ctx)