Skip to content

Commit

Permalink
implemented http request auto retry feature
Browse files Browse the repository at this point in the history
  • Loading branch information
mmadariaga committed Oct 9, 2024
1 parent 93e107d commit 0a95636
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 9 deletions.
2 changes: 1 addition & 1 deletion internal/infrastructure/service/FetchDriversByRace.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type Driver = domain_model.Driver
func FetchDriversByRace(raceId int) ([]Driver, error) {

targetUrl := "https://api.openf1.org/v1/drivers?session_key=" + strconv.Itoa(raceId)
body, err := helper.HttpGet(targetUrl, true)
body, err := helper.HttpGet(targetUrl, &helper.HttpGetExtraArgs{UseCache: true, Retry: true})
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/infrastructure/service/FetchPodiumByRace.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type Position struct {
func FetchPodiumByRace(raceId int, drivers []domain_model.Driver) ([3]Podium, error) {

targetUrl := "https://api.openf1.org/v1/position?position<=3&session_key=" + strconv.Itoa(raceId)
body, err := helper.HttpGet(targetUrl, true)
body, err := helper.HttpGet(targetUrl, &helper.HttpGetExtraArgs{UseCache: true, Retry: true})
if err != nil {
return [3]Podium{}, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/infrastructure/service/FetchRacesByYear.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type Race = domain_model.Race
func FetchRacesByYear(year int) ([]Race, error) {

targetUrl := "https://api.openf1.org/v1/sessions?year=" + strconv.Itoa(year) + "&session_type=Race"
body, err := helper.HttpGet(targetUrl, true)
body, err := helper.HttpGet(targetUrl, &helper.HttpGetExtraArgs{UseCache: true, Retry: true})
if err != nil {
return nil, err
}
Expand Down
38 changes: 32 additions & 6 deletions internal/infrastructure/service/helper/HttpGet.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"io"
"math/rand"
"net/http"
"sync"
"time"
Expand All @@ -19,14 +20,27 @@ type cacheValue struct {
var reqCache = make(map[string]cacheValue)
var rwMutex sync.RWMutex

func HttpGet(targetUrl string, useCache bool) ([]byte, error) {
type HttpGetExtraArgs struct {
UseCache bool
Retry bool
RetryCount int
}

const MAX_RETRIES = 2

func HttpGet(targetUrl string, args *HttpGetExtraArgs) ([]byte, error) {

if args.RetryCount > 0 {
delay := time.Duration(args.RetryCount*2500 + rand.Intn(1000))
time.Sleep(delay * time.Millisecond)
}

rwMutex.RLock()
cachedValue, isCached := reqCache[targetUrl]
rwMutex.RUnlock()

now := time.Now().Unix()
useCachedValue := useCache && isCached && now <= cachedValue.validUntil
useCachedValue := args.UseCache && isCached && now <= cachedValue.validUntil

if useCachedValue {
return cachedValue.value, nil
Expand All @@ -35,6 +49,13 @@ func HttpGet(targetUrl string, useCache bool) ([]byte, error) {
// Fetch data
resp, err := http.Get(targetUrl)
if err != nil || resp.StatusCode < 200 || resp.StatusCode >= 300 {

if args.Retry && args.RetryCount < MAX_RETRIES {
log.Debug().Msg("Request error. Retrying request to " + targetUrl)
args.RetryCount++
return HttpGet(targetUrl, args)
}

errorMsg := fmt.Sprintf("Request error: %v at %v", err, targetUrl)
log.Error().Msg(errorMsg)

Expand All @@ -46,22 +67,27 @@ func HttpGet(targetUrl string, useCache bool) ([]byte, error) {
// Extract body
body, err := io.ReadAll(resp.Body)
if err != nil {
if args.Retry && args.RetryCount < MAX_RETRIES {
log.Debug().Msg("Error reading response body. Retrying request to " + targetUrl)
args.RetryCount++
return HttpGet(targetUrl, args)
}

errorMsg := fmt.Sprintf("Error reading response body: %v", err)
log.Error().Msg(errorMsg)

return nil, errors.New(errorMsg)
}

if useCache {
tenMinuteAfter := time.Now().Add(10 * time.Minute).Unix()
if args.UseCache {
oneHour := time.Now().Add(60 * time.Minute).Unix()

rwMutex.Lock()
reqCache[targetUrl] = cacheValue{
validUntil: tenMinuteAfter,
validUntil: oneHour,
value: body,
}
rwMutex.Unlock()

}

return body, nil
Expand Down

0 comments on commit 0a95636

Please sign in to comment.