Browse Source

Merge pull request #7269 from sinsharat/use_requestWithContext_for_cancel

*: Use http.Request.WithContext instead of Cancel
Xiang Li 9 years ago
parent
commit
56c706ff91
3 changed files with 22 additions and 49 deletions
  1. 18 36
      lease/leasehttp/http.go
  2. 0 9
      pkg/httputil/httputil.go
  3. 4 4
      proxy/httpproxy/reverse.go

+ 18 - 36
lease/leasehttp/http.go

@@ -16,6 +16,7 @@ package leasehttp
 
 
 import (
 import (
 	"bytes"
 	"bytes"
+	"context"
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
 	"io/ioutil"
 	"io/ioutil"
@@ -26,7 +27,6 @@ import (
 	"github.com/coreos/etcd/lease"
 	"github.com/coreos/etcd/lease"
 	"github.com/coreos/etcd/lease/leasepb"
 	"github.com/coreos/etcd/lease/leasepb"
 	"github.com/coreos/etcd/pkg/httputil"
 	"github.com/coreos/etcd/pkg/httputil"
-	"golang.org/x/net/context"
 )
 )
 
 
 var (
 var (
@@ -202,45 +202,27 @@ func TimeToLiveHTTP(ctx context.Context, id lease.LeaseID, keys bool, url string
 	}
 	}
 	req.Header.Set("Content-Type", "application/protobuf")
 	req.Header.Set("Content-Type", "application/protobuf")
 
 
-	cancel := httputil.RequestCanceler(req)
+	req = req.WithContext(ctx)
 
 
 	cc := &http.Client{Transport: rt}
 	cc := &http.Client{Transport: rt}
 	var b []byte
 	var b []byte
 	// buffer errc channel so that errc don't block inside the go routinue
 	// buffer errc channel so that errc don't block inside the go routinue
-	errc := make(chan error, 2)
-	go func() {
-		resp, err := cc.Do(req)
-		if err != nil {
-			errc <- err
-			return
-		}
-		b, err = readResponse(resp)
-		if err != nil {
-			errc <- err
-			return
-		}
-		if resp.StatusCode == http.StatusRequestTimeout {
-			errc <- ErrLeaseHTTPTimeout
-			return
-		}
-		if resp.StatusCode == http.StatusNotFound {
-			errc <- lease.ErrLeaseNotFound
-			return
-		}
-		if resp.StatusCode != http.StatusOK {
-			errc <- fmt.Errorf("lease: unknown error(%s)", string(b))
-			return
-		}
-		errc <- nil
-	}()
-	select {
-	case derr := <-errc:
-		if derr != nil {
-			return nil, derr
-		}
-	case <-ctx.Done():
-		cancel()
-		return nil, ctx.Err()
+	resp, err := cc.Do(req)
+	if err != nil {
+		return nil, err
+	}
+	b, err = readResponse(resp)
+	if err != nil {
+		return nil, err
+	}
+	if resp.StatusCode == http.StatusRequestTimeout {
+		return nil, ErrLeaseHTTPTimeout
+	}
+	if resp.StatusCode == http.StatusNotFound {
+		return nil, lease.ErrLeaseNotFound
+	}
+	if resp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf("lease: unknown error(%s)", string(b))
 	}
 	}
 
 
 	lresp := &leasepb.LeaseInternalResponse{}
 	lresp := &leasepb.LeaseInternalResponse{}

+ 0 - 9
pkg/httputil/httputil.go

@@ -13,15 +13,6 @@ import (
 	"net/http"
 	"net/http"
 )
 )
 
 
-func RequestCanceler(req *http.Request) func() {
-	ch := make(chan struct{})
-	req.Cancel = ch
-
-	return func() {
-		close(ch)
-	}
-}
-
 // GracefulClose drains http.Response.Body until it hits EOF
 // GracefulClose drains http.Response.Body until it hits EOF
 // and closes it. This prevents TCP/TLS connections from closing,
 // and closes it. This prevents TCP/TLS connections from closing,
 // therefore available for reuse.
 // therefore available for reuse.

+ 4 - 4
proxy/httpproxy/reverse.go

@@ -16,6 +16,7 @@ package httpproxy
 
 
 import (
 import (
 	"bytes"
 	"bytes"
+	"context"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 	"io/ioutil"
 	"io/ioutil"
@@ -24,11 +25,9 @@ import (
 	"net/url"
 	"net/url"
 	"strings"
 	"strings"
 	"sync/atomic"
 	"sync/atomic"
-
 	"time"
 	"time"
 
 
 	"github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
 	"github.com/coreos/etcd/etcdserver/api/v2http/httptypes"
-	"github.com/coreos/etcd/pkg/httputil"
 	"github.com/coreos/pkg/capnslog"
 	"github.com/coreos/pkg/capnslog"
 )
 )
 
 
@@ -110,7 +109,9 @@ func (p *reverseProxy) ServeHTTP(rw http.ResponseWriter, clientreq *http.Request
 	var requestClosed int32
 	var requestClosed int32
 	completeCh := make(chan bool, 1)
 	completeCh := make(chan bool, 1)
 	closeNotifier, ok := rw.(http.CloseNotifier)
 	closeNotifier, ok := rw.(http.CloseNotifier)
-	cancel := httputil.RequestCanceler(proxyreq)
+	ctx, cancel := context.WithCancel(context.Background())
+	proxyreq = proxyreq.WithContext(ctx)
+	defer cancel()
 	if ok {
 	if ok {
 		closeCh := closeNotifier.CloseNotify()
 		closeCh := closeNotifier.CloseNotify()
 		go func() {
 		go func() {
@@ -118,7 +119,6 @@ func (p *reverseProxy) ServeHTTP(rw http.ResponseWriter, clientreq *http.Request
 			case <-closeCh:
 			case <-closeCh:
 				atomic.StoreInt32(&requestClosed, 1)
 				atomic.StoreInt32(&requestClosed, 1)
 				plog.Printf("client %v closed request prematurely", clientreq.RemoteAddr)
 				plog.Printf("client %v closed request prematurely", clientreq.RemoteAddr)
-				cancel()
 			case <-completeCh:
 			case <-completeCh:
 			}
 			}
 		}()
 		}()