Files
plexgo/retry/config.go

149 lines
3.6 KiB
Go

// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
package retry
import (
"errors"
"net/http"
"strconv"
"time"
)
// BackoffStrategy defines the parameters for exponential backoff. This can be
// used to drive a retry loop for example.
type BackoffStrategy struct {
InitialInterval int
MaxInterval int
Exponent float64
MaxElapsedTime int
}
// Config configures a retry policy.
type Config struct {
// Strategy sets the algorithm to use for a retry loop. It can be one of:
// - "backoff": retry with exponential backoff and random jitter.
// - "none" or "": disables retries.
Strategy string
Backoff *BackoffStrategy
RetryConnectionErrors bool
}
// PermanentError is an error that signals that some operation has terminally
// failed and should not be retried.
type PermanentError struct {
cause error
}
// Permanent creates a PermanentError that signals to a retry loop that it
// should stop retrying an operation and return the underlying error.
func Permanent(cause error) error {
if IsPermanentError(cause) {
return cause
}
return &PermanentError{
cause: cause,
}
}
func (e *PermanentError) Error() string {
return e.cause.Error()
}
func (e *PermanentError) Unwrap() error {
return e.cause
}
// TemporaryError represents a retryable error and signals to a retry loop that
// an operation may be retried with an optional wait interval.
type TemporaryError struct {
wait time.Duration
message string
}
// Temporary creates a TemporaryError that signals to a retry loop that an
// operation can be retried. The error may also carry details about how long to
// wait before retrying. This wait interval may be used to override the retry
// policy in use.
func Temporary(message string) error {
return &TemporaryError{
message: message,
}
}
// TemporaryFromResponse creates a TemporaryError similar to Temporary but
// additionally parses the Retry-After header from a response to determine the
// wait interval before the next retry attempt.
func TemporaryFromResponse(message string, res *http.Response) error {
return &TemporaryError{
wait: retryIntervalFromResponse(res),
message: message,
}
}
func (e *TemporaryError) Error() string {
return e.message
}
// RetryAfter returns the time to wait before retrying the request. The zero
// value should be interpreted by retry loops to mean they should fallback on
// their default policy whether expenonential, constant backoff or something
// else. It does not mean that an operation should be retried immediately.
func (e *TemporaryError) RetryAfter() time.Duration {
return e.wait
}
func retryIntervalFromResponse(res *http.Response) time.Duration {
if res == nil {
return 0
}
retryVal := res.Header.Get("retry-after")
if retryVal == "" {
return 0
}
parsedNumber, err := strconv.ParseInt(retryVal, 10, 64)
if err == nil {
if parsedNumber < 0 {
return 0
} else {
return time.Duration(parsedNumber) * time.Second
}
}
parsedDate, err := time.Parse(time.RFC1123, retryVal)
if err == nil {
delta := parsedDate.Sub(time.Now())
if delta < 0 {
return 0
} else {
return delta
}
}
return 0
}
// IsPermanentError returns true if an error value is or contains a
// PermanentError in its chain of errors.
func IsPermanentError(err error) bool {
if err == nil {
return false
}
var pe *PermanentError
return errors.As(err, &pe)
}
// IsTemporaryError returns true if an error value is or contains a
// TemporaryError in its chain of errors.
func IsTemporaryError(err error) bool {
if err == nil {
return false
}
var pe *TemporaryError
return errors.As(err, &pe)
}