fix: correct int overflow bug, add fixed delay, and rename env for retries

This commit is contained in:
Phillip Thurston
2025-03-10 15:22:30 -06:00
committed by lovelaze
parent b83c8354ca
commit 3ffb40f2a9
4 changed files with 82 additions and 4 deletions
+1 -1
View File
@@ -85,7 +85,7 @@ The following environment variables can be specified:
| `RUN_GRAVITY` | false | true | Specifies whether to run gravity after syncing |
| `TZ` | n/a | `Europe/London` | Specifies the timezone for logs and cron |
| `CLIENT_SKIP_TLS_VERIFICATION` | false | true | Skips SSL certificate verification |
| `CLIENT_RETRY_DELAY` | 1 | 5 | Seconds to delay betweeen connection attempts |
| `CLIENT_RETRY_DELAY_SECONDS` | 1 | 5 | Seconds to delay betweeen connection attempts |
> **Note:** The following optional settings apply only if `FULL_SYNC=false`. They allow for granular control of synchronization if a full sync is not wanted.
+2 -2
View File
@@ -20,8 +20,8 @@ type Config struct {
}
type Client struct {
SkipSSLVerification bool `default:"false" envconfig:"CLIENT_SKIP_TLS_VERIFICATION"`
RetryDelay uint `default:"1" envconfig:"CLIENT_RETRY_DELAY"`
SkipSSLVerification bool `default:"false" envconfig:"CLIENT_SKIP_TLS_VERIFICATION"`
RetryDelay int64 `default:"1" envconfig:"CLIENT_RETRY_DELAY_SECONDS"`
}
type GravitySettings struct {
+2 -1
View File
@@ -16,13 +16,14 @@ const (
AttemptsDeleteSession = 3
)
func withRetry(retryFunc func() error, attempts, delay uint) error {
func withRetry(retryFunc func() error, attempts uint, delay int64) error {
return retry.Do(
func() error {
return retryFunc()
},
retry.Attempts(attempts),
retry.Delay(time.Duration(delay)*time.Second),
retry.DelayType(retry.FixedDelay),
retry.OnRetry(func(n uint, err error) {
log.Debug().Msg(fmt.Sprintf("Retrying(%d): %v", n+1, err))
}),
+77
View File
@@ -0,0 +1,77 @@
package sync
import (
"errors"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
// Test that the retries are actually causing the expected
// delay and additionally make sure they are a fixed delay
// and not the default backoff value.
func TestWithRetry_DelayBetweenRetries(t *testing.T) {
t.Parallel()
counter := 0
start := time.Now()
err := withRetry(func() error {
counter++
if counter < 3 {
return errors.New("test error")
}
return nil
}, 3, 1) // 3 attempts, 1-second delay
elapsed := time.Since(start)
assert.NoError(t, err, "Expected success before max attempts")
assert.GreaterOrEqual(t, elapsed.Seconds(), 2.0, "Expected at least 2 seconds of delay between all retries")
assert.LessOrEqual(t, elapsed.Seconds(), 2.5, "Expected at most 2.5 seconds of delay between all retries")
}
// Test that we do not retry on immediate success.
func TestWithRetry_NoRetriesOnImmediateSuccess(t *testing.T) {
t.Parallel()
counter := 0
err := withRetry(func() error {
counter++
return nil
}, 5, 2) // 5 attempts, 2-second delay
assert.NoError(t, err, "Expected no error when function succeeds immediately")
assert.Equal(t, 1, counter, "Expected function to run only once without retries")
}
// Test that we properly succeed after a few but not max retires.
func TestWithRetry_SuccessAfterRetries(t *testing.T) {
t.Parallel()
counter := 0
err := withRetry(func() error {
counter++
if counter < 2 {
return errors.New("test error")
}
return nil
}, 3, 1) // 3 attempts, 1-second delay
assert.NoError(t, err, "Expected success before max attempts")
assert.Equal(t, 2, counter, "Expected function to retry once before success")
}
// Test to make sure we properly fail after max amount of retries.
func TestWithRetry_MaxAttemptsFailure(t *testing.T) {
t.Parallel()
counter := 0
err := withRetry(func() error {
counter++
return errors.New("test error")
}, 3, 1) // 3 attempts, 1-second delay
assert.Error(t, err, "Expected an error after max attempts")
assert.Equal(t, 3, counter, "Expected function to be retried 3 times")
}