Retry simulation for https://github.com/wal-g/wal-g/blob/feb60cc7d25056c443b310f99639c6effe32c01c/pkg/storages/s3/folder.go#L51
Copy and paste to https://go.dev/play/
or
place code in file retry_simulation.go and run go run retry_simulation.go
Retry simulation for https://github.com/wal-g/wal-g/blob/feb60cc7d25056c443b310f99639c6effe32c01c/pkg/storages/s3/folder.go#L51
Copy and paste to https://go.dev/play/
or
place code in file retry_simulation.go and run go run retry_simulation.go
| package main | |
| import ( | |
| "errors" | |
| "log" | |
| "math" | |
| "math/rand" | |
| "time" | |
| ) | |
| var ( | |
| RangeMaxRetriesDefault = 10 | |
| RangeQueryMinRetryDelay = 30 * time.Millisecond | |
| RangeQueryMaxRetryDelay = 300 * time.Second | |
| MaxRetriesDefault = 15 | |
| ) | |
| func getReaderSettings() (rangeEnabled bool, retriesCount int, minRetryDelay, maxRetryDelay time.Duration) { | |
| rangeEnabled = true | |
| retriesCount = RangeMaxRetriesDefault | |
| if minRetryDelay == 0 { | |
| minRetryDelay = RangeQueryMinRetryDelay | |
| } | |
| if maxRetryDelay == 0 { | |
| maxRetryDelay = RangeQueryMaxRetryDelay | |
| } | |
| return rangeEnabled, retriesCount, minRetryDelay, maxRetryDelay | |
| } | |
| func simulateRangeQuery() error { | |
| return errors.New("simulated range query error") | |
| } | |
| func getJitterDelay(duration time.Duration) time.Duration { | |
| return time.Duration(rand.Int63n(int64(duration)) + int64(duration)) | |
| } | |
| func getIncrSleep(retryCount int, minDelay time.Duration, maxDelay time.Duration) time.Duration { | |
| var delay time.Duration | |
| actualRetryCount := int(math.Log2(float64(minDelay))) + 1 | |
| if actualRetryCount < 63-retryCount { | |
| delay = time.Duration(1<<uint64(retryCount)) * getJitterDelay(minDelay) | |
| if delay > maxDelay { | |
| delay = getJitterDelay(maxDelay / 2) | |
| } | |
| } else { | |
| delay = getJitterDelay(maxDelay / 2) | |
| } | |
| return delay | |
| } | |
| func main() { | |
| rangeEnabled, retriesCount, minRetryDelay, maxRetryDelay := getReaderSettings() | |
| log.Printf("rangeEnabled: %v, retriesCount: %v, minRetryDelay: %v, maxRetryDelay: %v", rangeEnabled, retriesCount, minRetryDelay, maxRetryDelay) | |
| for i := 1; i <= retriesCount; i++ { | |
| log.Printf("Retry #%d for range query", i) | |
| err := simulateRangeQuery() | |
| if err == nil { | |
| log.Println("Range query successful!") | |
| break | |
| } | |
| if i == retriesCount { | |
| log.Println("Max retries reached, giving up.") | |
| break | |
| } | |
| // Calculate the retry delay | |
| retryDelay := getIncrSleep(i, minRetryDelay, maxRetryDelay) | |
| log.Printf("Range query failed. Retrying in %v...", retryDelay) | |
| //time.Sleep(retryDelay) | |
| } | |
| log.Println("Simulation finished.") | |
| } |