dax/internal/client/dax_retryer.go (59 lines of code) (raw):

/* Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at http://www.apache.org/licenses/LICENSE-2.0 or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package client import ( "math/rand" "time" ) // DaxRetryer implements retry strategy with equal jitter backoff for throttled requests type DaxRetryer struct { BaseThrottleDelay time.Duration MaxBackoffDelay time.Duration } const ( // DefaultBaseRetryDelay is base delay for throttled requests DefaultBaseRetryDelay = 70 * time.Millisecond // DefaultMaxBackoffDelay is max backoff delay for throttled requests DefaultMaxBackoffDelay = 20 * time.Second ) func (r *DaxRetryer) setRetryerDefaults() { if r.BaseThrottleDelay == 0 { r.BaseThrottleDelay = DefaultBaseRetryDelay } if r.MaxBackoffDelay == 0 { r.MaxBackoffDelay = DefaultMaxBackoffDelay } } // RetryDelay returns the delay duration before retrying this request again func (r DaxRetryer) RetryDelay(attempts int, err error) time.Duration { if IsThrottleError(err) { r.setRetryerDefaults() minDelay := time.Duration(1<<uint64(attempts)) * r.BaseThrottleDelay if minDelay > r.MaxBackoffDelay { minDelay = r.MaxBackoffDelay } jitter := time.Duration(rand.Intn(int(minDelay)/2 + 1)) return minDelay/2 + jitter } return 0 } // MaxAttempts returns the maximum number of retry attempts func (r DaxRetryer) MaxAttempts() int { return 0 // You can adjust this value based on your requirements } // IsErrorRetryable returns if the error is daxError // if code sequences correct any condition return a value other than unknown. func (r DaxRetryer) IsErrorRetryable(err error) bool { if IsThrottleError(err) { return true } de, ok := err.(daxError) if !ok { return false } codes := de.CodeSequence() if len(codes) > 0 && (codes[0] == 1 || codes[0] == 2) { return true } // Error code [4.23.31.33] is for AuthenticationRequiredException if isAuthCRequiredException(codes) { return true } return false } // Error code [4.23.31.33] is for AuthenticationRequiredException func isAuthCRequiredException(codes []int) bool { return len(codes) == 4 && codes[0] == 4 && codes[1] == 23 && codes[2] == 31 && codes[3] == 33 } func isRetryable(o RequestOptions, err error) bool { return o.Retryer.IsErrorRetryable(err) }