diff --git a/retries.go b/retries.go index 2a48bb818..a5fb7d4c1 100644 --- a/retries.go +++ b/retries.go @@ -9,7 +9,10 @@ import ( "github.com/go-resty/resty/v2" ) -const retryAfterHeaderName = "Retry-After" +const ( + retryAfterHeaderName = "Retry-After" + maintenanceModeHeaderName = "X-Maintenance-Mode" +) // type RetryConditional func(r *resty.Response) (shouldRetry bool) type RetryConditional resty.RetryConditionFunc @@ -54,7 +57,17 @@ func tooManyRequestsRetryCondition(r *resty.Response, _ error) bool { } func serviceUnavailableRetryCondition(r *resty.Response, _ error) bool { - return r.StatusCode() == http.StatusServiceUnavailable + serviceUnavailable := r.StatusCode() == http.StatusServiceUnavailable + + // During maintenance events, the API will return a 503 and add + // an `X-MAINTENANCE-MODE` header. Don't retry during maintenance + // events, only for legitimate 503s. + if serviceUnavailable && r.Header().Get(maintenanceModeHeaderName) != "" { + log.Printf("[INFO] Linode API is under maintenance, request will not be retried - please see status.linode.com for more information") + return false + } + + return serviceUnavailable } func requestTimeoutRetryCondition(r *resty.Response, _ error) bool { diff --git a/retries_test.go b/retries_test.go index ce744b3a7..4f0029388 100644 --- a/retries_test.go +++ b/retries_test.go @@ -58,3 +58,19 @@ func TestLinodeServiceUnavailableRetryCondition(t *testing.T) { t.Errorf("expected retryAfter to be 20 but got %d", retryAfter) } } + +func TestLinodeServiceMaintenanceModeRetryCondition(t *testing.T) { + request := resty.Request{} + rawResponse := http.Response{StatusCode: http.StatusServiceUnavailable, Header: http.Header{ + retryAfterHeaderName: []string{"20"}, + maintenanceModeHeaderName: []string{"Currently in maintenance mode."}, + }} + response := resty.Response{ + Request: &request, + RawResponse: &rawResponse, + } + + if retry := serviceUnavailableRetryCondition(&response, nil); retry { + t.Error("expected retry to be skipped due to maintenance mode header") + } +}