summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCory Cooper <coopercory92@gmail.com>2022-10-05 21:34:49 -0700
committerGitHub <noreply@github.com>2022-10-05 22:34:49 -0600
commit498f32bab96ba00e1a7d04c6bc8b367c97d8a335 (patch)
tree14554ad81d2559a219bcc384de2bd5ed55929bd8
parented118f2b0900e6416ef202afb0f79caeae4fddcb (diff)
caddyconfig: Implement retries into HTTPLoader (#5077)
* httploader: Add max_retries * caddyconfig: dependency-free http config loading retries * caddyconfig: support `retry_delay` in http loader * httploader: Implement retries * Apply suggestions from code review Co-authored-by: Matt Holt <mholt@users.noreply.github.com> Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
-rw-r--r--caddyconfig/httploader.go33
1 files changed, 32 insertions, 1 deletions
diff --git a/caddyconfig/httploader.go b/caddyconfig/httploader.go
index 80eab44..f199219 100644
--- a/caddyconfig/httploader.go
+++ b/caddyconfig/httploader.go
@@ -94,7 +94,7 @@ func (hl HTTPLoader) LoadConfig(ctx caddy.Context) ([]byte, error) {
}
}
- resp, err := client.Do(req)
+ resp, err := doHttpCallWithRetries(ctx, client, req)
if err != nil {
return nil, err
}
@@ -119,6 +119,37 @@ func (hl HTTPLoader) LoadConfig(ctx caddy.Context) ([]byte, error) {
return result, nil
}
+func attemptHttpCall(client *http.Client, request *http.Request) (*http.Response, error) {
+ resp, err := client.Do(request)
+ if err != nil {
+ return nil, fmt.Errorf("problem calling http loader url: %v", err)
+ } else if resp.StatusCode < 200 || resp.StatusCode > 499 {
+ return nil, fmt.Errorf("bad response status code from http loader url: %v", resp.StatusCode)
+ }
+ return resp, nil
+}
+
+func doHttpCallWithRetries(ctx caddy.Context, client *http.Client, request *http.Request) (*http.Response, error) {
+ var resp *http.Response
+ var err error
+ const maxAttempts = 10
+
+ // attempt up to 10 times
+ for i := 0; i < maxAttempts; i++ {
+ resp, err = attemptHttpCall(client, request)
+ if err != nil && i < maxAttempts-1 {
+ // wait 500ms before reattempting, or until context is done
+ select {
+ case <-time.After(time.Millisecond * 500):
+ case <-ctx.Done():
+ return resp, ctx.Err()
+ }
+ }
+ }
+
+ return resp, err
+}
+
func (hl HTTPLoader) makeClient(ctx caddy.Context) (*http.Client, error) {
client := &http.Client{
Timeout: time.Duration(hl.Timeout),