Golang Request.Cancel Examples

Golang Request.Cancel - 14 examples found. These are the top rated real world Golang examples of net/http.Request.Cancel extracted from open source projects. You can rate examples to help us improve the quality of examples.
Example #1
0
File: api.go Project: qbit/client
// adapted from https://blog.golang.org/context httpDo func
func doTimeout(cli *Client, req *http.Request, timeout time.Duration) (*http.Response, error) {
	// TODO: could pass in a context from further up the chain
	// and use that instead of context.Background()
	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()

	// new way to cancel requests
	reqCancel := make(chan struct{})
	req.Cancel = reqCancel

	type response struct {
		resp *http.Response
		err  error
	}
	c := make(chan response, 1)
	go func() {
		var r response
		r.resp, r.err = cli.cli.Do(req)
		c <- r
	}()

	select {
	case <-ctx.Done():
		// request ctx timed out.  Cancel the request by closing req.Cancel channel:
		close(reqCancel)
		// wait for request to finish
		<-c
		return nil, ctx.Err()
	case r := <-c:
		// request successful
		return r.resp, r.err
	}

}
Example #2
0
func (t *transport) RoundTrip(ctx context.Context, req *http.Request, l log15.Logger) (*http.Response, error) {
	// http.Transport closes the request body on a failed dial, issue #875
	req.Body = &fakeCloseReadCloser{req.Body}
	defer req.Body.(*fakeCloseReadCloser).RealClose()

	// hook up CloseNotify to cancel the request
	req.Cancel = ctx.Done()

	stickyBackend := t.getStickyBackend(req)
	backends := t.getOrderedBackends(stickyBackend, req)
	allTimeout := len(backends) > 0
	for i, backend := range backends {
		req.URL.Host = backend
		res, err := httpTransport.RoundTrip(req)
		if err == nil {
			t.setStickyBackend(res, stickyBackend)
			return res, nil
		}
		if allTimeout && !strings.Contains(err.Error(), "timeout") {
			allTimeout = false
		}
		l.Error("retriable dial error", "backend", backend, "err", err, "attempt", i)
	}
	status, err := 503, errNoBackends
	if allTimeout {
		status, err = 504, errTimeout
	}
	l.Error("request failed", "status", status, "num_backends", len(backends))
	return nil, err
}
Example #3
0
// makeReqCancel returns a closure that cancels the given http.Request
// when called.
func makeReqCancel(req *http.Request) func(http.RoundTripper) {
	c := make(chan struct{})
	req.Cancel = c
	return func(http.RoundTripper) {
		close(c)
	}
}
Example #4
0
func (t *transport) RoundTrip(ctx context.Context, req *http.Request, l log15.Logger) (*http.Response, string, error) {
	// http.Transport closes the request body on a failed dial, issue #875
	req.Body = &fakeCloseReadCloser{req.Body}
	defer req.Body.(*fakeCloseReadCloser).RealClose()

	// hook up CloseNotify to cancel the request
	req.Cancel = ctx.Done()

	rt := ctx.Value(ctxKeyRequestTracker).(RequestTracker)
	stickyBackend := t.getStickyBackend(req)
	backends := t.getOrderedBackends(stickyBackend)
	for i, backend := range backends {
		req.URL.Host = backend
		rt.TrackRequestStart(backend)
		res, err := httpTransport.RoundTrip(req)
		if err == nil {
			t.setStickyBackend(res, stickyBackend)
			return res, backend, nil
		}
		rt.TrackRequestDone(backend)
		if _, ok := err.(dialErr); !ok {
			l.Error("unretriable request error", "backend", backend, "err", err, "attempt", i)
			return nil, "", err
		}
		l.Error("retriable dial error", "backend", backend, "err", err, "attempt", i)
	}
	l.Error("request failed", "status", "503", "num_backends", len(backends))
	return nil, "", errNoBackends
}
Example #5
0
func cancelable(client *http.Client, req *http.Request) func() {
	ch := make(chan struct{})
	req.Cancel = ch
	return func() {
		close(ch)
	}
}
Example #6
0
func (t *Transport) tries(req *http.Request, try uint) (*http.Response, error) {
	startTime := time.Now()
	var timer *time.Timer
	rCancler := make(chan struct{})
	req.Cancel = rCancler
	if t.RequestTimeout != 0 {
		timer = time.AfterFunc(t.RequestTimeout, func() {

			//t.CancelRequest(req)
			t.startOnce.Do(t.start)
			if bc, ok := req.Body.(*bodyCloser); ok {
				bc.timer.Stop()
			}
			close(rCancler)
			t.transport.CancelRequest(req)

		})
	}
	res, err := t.transport.RoundTrip(req)
	headerTime := time.Now()
	if err != nil {
		if timer != nil {
			timer.Stop()
		}
		var stats *Stats
		if t.Stats != nil {
			stats = &Stats{
				Request:  req,
				Response: res,
				Error:    err,
			}
			stats.Duration.Header = headerTime.Sub(startTime)
			stats.Retry.Count = try
		}

		if try < t.MaxTries && req.Method == "GET" && t.shouldRetryError(err) {
			if t.Stats != nil {
				stats.Retry.Pending = true
				t.Stats(stats)
			}
			return t.tries(req, try+1)
		}

		if t.Stats != nil {
			t.Stats(stats)
		}
		return nil, err
	}

	res.Body = &bodyCloser{
		ReadCloser: res.Body,
		timer:      timer,
		res:        res,
		transport:  t,
		startTime:  startTime,
		headerTime: headerTime,
	}
	return res, nil
}