Skip to content

Commit

Permalink
Tidy up and flattening
Browse files Browse the repository at this point in the history
  • Loading branch information
thejoeker12 committed Jul 8, 2024
1 parent 3b428e1 commit c9cd26f
Show file tree
Hide file tree
Showing 8 changed files with 26 additions and 331 deletions.
2 changes: 2 additions & 0 deletions httpclient/cookies.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import (
"net/url"
)

// loadCustomCookies applies the custom cookies supplied in the config and applies them to the http session.
func (c *Client) loadCustomCookies() error {
cookieJar, err := cookiejar.New(nil)
if err != nil {
return err
}

c.http.Jar = cookieJar

cookieUrl, err := url.Parse((*c.Integration).GetFQDN())
Expand Down
14 changes: 0 additions & 14 deletions httpclient/headers.go

This file was deleted.

14 changes: 8 additions & 6 deletions httpclient/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,18 @@ func (c *Client) DoRequest(method, endpoint string, body, out interface{}) (*htt
// - The retry mechanism employs exponential backoff with jitter to mitigate the impact of retries on the server.
// endregion
func (c *Client) executeRequestWithRetries(method, endpoint string, body interface{}) (*http.Response, error) {
ctx := context.Background()
totalRetryDeadline := time.Now().Add(c.config.TotalRetryDuration)

var resp *http.Response
var err error
var retryCount int

ctx := context.Background()

c.Sugar.Debug("Executing request with retries", zap.String("method", method), zap.String("endpoint", endpoint))

// TODO removed the blocked comments
// Simplify this?
// Timer
totalRetryDeadline := time.Now().Add(c.config.TotalRetryDuration)
for time.Now().Before(totalRetryDeadline) {

// Resp
Expand All @@ -133,21 +134,22 @@ func (c *Client) executeRequestWithRetries(method, endpoint string, body interfa
}

// Success
if resp.StatusCode >= 200 && resp.StatusCode < 400 {
if resp.StatusCode >= 300 {
if resp.StatusCode >= http.StatusOK && resp.StatusCode < http.StatusBadRequest {
if resp.StatusCode == http.StatusPermanentRedirect || resp.StatusCode == http.StatusTemporaryRedirect {
c.Sugar.Warn("Redirect response received", zap.Int("status_code", resp.StatusCode), zap.String("location", resp.Header.Get("Location")))
}
c.Sugar.Infof("%s request successful at %v", resp.Request.Method, resp.Request.URL)
return resp, nil
}

// Message
statusMessage := http.StatusText(resp.StatusCode)
if statusMessage == "" {
statusMessage = "unknown response code"
}

// Non Retry
if IsNonRetryableStatusCode(resp) {
if IsNonRetryableStatusCode(resp.StatusCode) {
c.Sugar.Warn("Non-retryable error received", zap.Int("status_code", resp.StatusCode), zap.String("status_message", statusMessage))
return resp, response.HandleAPIErrorResponse(resp, c.Sugar)
}
Expand Down
4 changes: 2 additions & 2 deletions httpclient/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package httpclient
import "net/http"

// IsNonRetryableStatusCode checks if the provided response indicates a non-retryable error.
func IsNonRetryableStatusCode(resp *http.Response) bool {
func IsNonRetryableStatusCode(statusCode int) bool {
nonRetryableStatusCodes := map[int]bool{
http.StatusBadRequest: true, // 400 - Bad Request
http.StatusUnauthorized: true, // 401 - Unauthorized
Expand Down Expand Up @@ -31,7 +31,7 @@ func IsNonRetryableStatusCode(resp *http.Response) bool {
http.StatusUnavailableForLegalReasons: true, // 451 - Unavailable For Legal Reasons
}

_, isNonRetryable := nonRetryableStatusCodes[resp.StatusCode]
_, isNonRetryable := nonRetryableStatusCodes[statusCode]
return isNonRetryable
}

Expand Down
9 changes: 9 additions & 0 deletions httpclient/utility.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package httpclient
import (
"errors"
"fmt"
"net/http"
"os"
"path/filepath"
"regexp"
Expand Down Expand Up @@ -152,3 +153,11 @@ func setDefaultDuration(field *time.Duration, defaultValue time.Duration) {
*field = defaultValue
}
}

// CheckDeprecationHeader checks the response headers for the Deprecation header and logs a warning if present.
func (c *Client) CheckDeprecationHeader(resp *http.Response) {
deprecationHeader := resp.Header.Get("Deprecation")
if deprecationHeader != "" {
c.Sugar.Warn("API endpoint is deprecated", deprecationHeader, resp.Request.URL.String())
}
}
16 changes: 5 additions & 11 deletions ratehandler/ratehandler.go → ratehandler/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,8 @@ const (
// The jitterFactor adds randomness to the delay to avoid simultaneous retries (thundering herd problem).
// The delay is capped at maxDelay to prevent excessive wait times.
func CalculateBackoff(retry int) time.Duration {
if retry < 0 {
retry = 0 // Ensure non-negative retry count
}

delay := float64(baseDelay) * math.Pow(2, float64(retry))

jitter := (rand.Float64() - 0.5) * jitterFactor * 2.0 // Random value between -jitterFactor and +jitterFactor
delayWithJitter := delay * (1.0 + jitter)

Expand All @@ -57,32 +54,29 @@ func CalculateBackoff(retry int) time.Duration {
// ParseRateLimitHeaders parses common rate limit headers and adjusts behavior accordingly.
// It handles both Retry-After (in seconds or HTTP-date format) and X-RateLimit-Reset headers.
func ParseRateLimitHeaders(resp *http.Response, logger *zap.SugaredLogger) time.Duration {
// Check for the Retry-After header in seconds
if retryAfter := resp.Header.Get("Retry-After"); retryAfter != "" {
if waitSeconds, err := strconv.Atoi(retryAfter); err == nil {
return time.Duration(waitSeconds) * time.Second

} else if retryAfterDate, err := time.Parse(time.RFC1123, retryAfter); err == nil {
// Handle HTTP-date format in Retry-After
return time.Until(retryAfterDate)

} else {
logger.Debug("Unable to parse Retry-After header", zap.String("value", retryAfter), zap.Error(err))
}
}

// Check for X-RateLimit-Remaining; if it's 0, use X-RateLimit-Reset to determine how long to wait
if remaining := resp.Header.Get("X-RateLimit-Remaining"); remaining == "0" {
if resetTimeStr := resp.Header.Get("X-RateLimit-Reset"); resetTimeStr != "" {
if resetTimeEpoch, err := strconv.ParseInt(resetTimeStr, 10, 64); err == nil {
resetTime := time.Unix(resetTimeEpoch, 0)
// Add a buffer to account for potential clock skew
const skewBuffer = 5 * time.Second
return time.Until(resetTime) + skewBuffer
return time.Until(resetTime) + (5 * time.Second)

} else {
logger.Debug("Unable to parse X-RateLimit-Reset header", zap.String("value", resetTimeStr), zap.Error(err))
}
}
}

// No relevant rate limiting headers found, return 0
return 0
}
101 changes: 0 additions & 101 deletions ratehandler/ratehandler_test.go.bk

This file was deleted.

Loading

0 comments on commit c9cd26f

Please sign in to comment.