mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
vmctl: finish retries if context canceled (#4442)
vmctl: interrupt backoff retries if import context is cancelled Co-authored-by: Roman Khavronenko <roman@victoriametrics.com>
This commit is contained in:
parent
0e0b7bf87f
commit
2e81c5f740
3 changed files with 38 additions and 3 deletions
|
@ -42,7 +42,6 @@ func New() *Backoff {
|
||||||
func (b *Backoff) Retry(ctx context.Context, cb retryableFunc) (uint64, error) {
|
func (b *Backoff) Retry(ctx context.Context, cb retryableFunc) (uint64, error) {
|
||||||
var attempt uint64
|
var attempt uint64
|
||||||
for i := 0; i < b.retries; i++ {
|
for i := 0; i < b.retries; i++ {
|
||||||
// @TODO we should use context to cancel retries
|
|
||||||
err := cb()
|
err := cb()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return attempt, nil
|
return attempt, nil
|
||||||
|
@ -55,7 +54,19 @@ func (b *Backoff) Retry(ctx context.Context, cb retryableFunc) (uint64, error) {
|
||||||
backoff := float64(b.minDuration) * math.Pow(b.factor, float64(i))
|
backoff := float64(b.minDuration) * math.Pow(b.factor, float64(i))
|
||||||
dur := time.Duration(backoff)
|
dur := time.Duration(backoff)
|
||||||
logger.Errorf("got error: %s on attempt: %d; will retry in %v", err, attempt, dur)
|
logger.Errorf("got error: %s on attempt: %d; will retry in %v", err, attempt, dur)
|
||||||
time.Sleep(time.Duration(backoff))
|
|
||||||
|
t := time.NewTimer(dur)
|
||||||
|
select {
|
||||||
|
case <-t.C:
|
||||||
|
// duration elapsed, loop
|
||||||
|
case <-ctx.Done():
|
||||||
|
// context cancelled, kill the timer if it hasn't fired, and return
|
||||||
|
// the last error we got
|
||||||
|
if !t.Stop() {
|
||||||
|
<-t.C
|
||||||
|
}
|
||||||
|
return attempt, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return attempt, fmt.Errorf("execution failed after %d retry attempts", b.retries)
|
return attempt, fmt.Errorf("execution failed after %d retry attempts", b.retries)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ func TestRetry_Do(t *testing.T) {
|
||||||
backoffMinDuration time.Duration
|
backoffMinDuration time.Duration
|
||||||
retryableFunc retryableFunc
|
retryableFunc retryableFunc
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
withCancel bool
|
cancelTimeout time.Duration
|
||||||
want uint64
|
want uint64
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
|
@ -79,10 +79,33 @@ func TestRetry_Do(t *testing.T) {
|
||||||
want: 5,
|
want: 5,
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "cancel context",
|
||||||
|
backoffRetries: 5,
|
||||||
|
backoffFactor: 0.1,
|
||||||
|
backoffMinDuration: time.Millisecond * 10,
|
||||||
|
retryableFunc: func() error {
|
||||||
|
t := time.NewTicker(time.Millisecond * 5)
|
||||||
|
defer t.Stop()
|
||||||
|
for range t.C {
|
||||||
|
return fmt.Errorf("got some error")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
ctx: context.Background(),
|
||||||
|
cancelTimeout: time.Second * 5,
|
||||||
|
want: 3,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
r := New()
|
r := New()
|
||||||
|
if tt.cancelTimeout != 0 {
|
||||||
|
newCtx, cancelFn := context.WithTimeout(tt.ctx, tt.cancelTimeout)
|
||||||
|
tt.ctx = newCtx
|
||||||
|
defer cancelFn()
|
||||||
|
}
|
||||||
got, err := r.Retry(tt.ctx, tt.retryableFunc)
|
got, err := r.Retry(tt.ctx, tt.retryableFunc)
|
||||||
if (err != nil) != tt.wantErr {
|
if (err != nil) != tt.wantErr {
|
||||||
t.Errorf("Retry() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("Retry() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
|
|
@ -27,6 +27,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
|
||||||
* SECURITY: upgrade Go builder from Go1.20.4 to Go1.20.5. See [the list of issues addressed in Go1.20.5](https://github.com/golang/go/issues?q=milestone%3AGo1.20.5+label%3ACherryPickApproved).
|
* SECURITY: upgrade Go builder from Go1.20.4 to Go1.20.5. See [the list of issues addressed in Go1.20.5](https://github.com/golang/go/issues?q=milestone%3AGo1.20.5+label%3ACherryPickApproved).
|
||||||
|
|
||||||
* FEATURE: [vmctl](https://docs.victoriametrics.com/vmctl.html): add verbose output for docker installations or when TTY isn't available. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4081).
|
* FEATURE: [vmctl](https://docs.victoriametrics.com/vmctl.html): add verbose output for docker installations or when TTY isn't available. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/4081).
|
||||||
|
* FEATURE: [vmctl](https://docs.victoriametrics.com/vmctl.html): interrupt backoff retries when import process is cancelled. The change makes vmctl more responsive in case of errors during the import. See [this pull request](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4442).
|
||||||
* FEATURE: vmstorage: suppress "broken pipe" errors for search queries on vmstorage side. See [this commit](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4418/commits/a6a7795b9e1f210d614a2c5f9a3016b97ded4792).
|
* FEATURE: vmstorage: suppress "broken pipe" errors for search queries on vmstorage side. See [this commit](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/4418/commits/a6a7795b9e1f210d614a2c5f9a3016b97ded4792).
|
||||||
* FEATURE: [Official Grafana dashboards for VictoriaMetrics](https://grafana.com/orgs/victoriametrics): add panel for tracking rate of syscalls while writing or reading from disk via `process_io_(read|write)_syscalls_total` metrics.
|
* FEATURE: [Official Grafana dashboards for VictoriaMetrics](https://grafana.com/orgs/victoriametrics): add panel for tracking rate of syscalls while writing or reading from disk via `process_io_(read|write)_syscalls_total` metrics.
|
||||||
* FEATURE: add ability to fine-tune Graphite API limits via the following command-line flags:
|
* FEATURE: add ability to fine-tune Graphite API limits via the following command-line flags:
|
||||||
|
|
Loading…
Reference in a new issue