Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // Package httputil contains HTTP utility functions. | |
| 6 package httputil | |
| 7 | |
| 8 import ( | |
| 9 "bytes" | |
| 10 "fmt" | |
| 11 "io/ioutil" | |
| 12 "net/http" | |
| 13 "time" | |
| 14 | |
| 15 "golang.org/x/net/context" | |
| 16 "golang.org/x/net/context/ctxhttp" | |
| 17 | |
| 18 "github.com/luci/luci-go/common/clock" | |
| 19 "github.com/luci/luci-go/common/errors" | |
| 20 "github.com/luci/luci-go/common/logging" | |
| 21 "github.com/luci/luci-go/common/retry" | |
| 22 ) | |
| 23 | |
| 24 // RetryRequest retires an HTTP request on transient errors, | |
| 25 // calls fn on success and guarantees to close response body. | |
| 26 // ctx deadline is limited to client's timeout. | |
|
seanmccullough1
2016/06/03 18:45:33
Nice. Does this do exponential back-off?
nodir
2016/06/03 18:56:12
retry.Default does
updated docstring
| |
| 27 func RetryRequest(ctx context.Context, client *http.Client, req *http.Request, r equestBody []byte, fn func(*http.Response) error) error { | |
| 28 if client == nil { | |
| 29 client = http.DefaultClient | |
| 30 } | |
| 31 return retry.Retry( | |
| 32 ctx, | |
| 33 retry.TransientOnly(retry.Default), | |
| 34 func() error { | |
| 35 ctx := ctx | |
| 36 if client.Timeout > 0 { | |
| 37 clientDeadline := clock.Now(ctx).Add(client.Time out) | |
| 38 if deadline, ok := ctx.Deadline(); !ok || deadli ne.After(clientDeadline) { | |
| 39 ctx, _ = context.WithDeadline(ctx, clien tDeadline) | |
| 40 } | |
| 41 } | |
| 42 req.Body = ioutil.NopCloser(bytes.NewReader(requestBody) ) | |
| 43 res, err := ctxhttp.Do(ctx, client, req) | |
| 44 if err != nil { | |
| 45 return errors.WrapTransient(err) | |
| 46 } | |
| 47 defer res.Body.Close() | |
| 48 if res.StatusCode >= 500 { | |
| 49 return errors.WrapTransient(fmt.Errorf("HTTP sta tus %s", res.Status)) | |
| 50 } | |
| 51 return fn(res) | |
| 52 }, | |
| 53 func(err error, delay time.Duration) { | |
| 54 logging.Warningf(ctx, "failed transiently, will retry in %s: %s", delay, err) | |
| 55 }) | |
| 56 } | |
| OLD | NEW |