Skip to content

Commit

Permalink
wait: avoid leaky timer pattern (#85)
Browse files Browse the repository at this point in the history
  • Loading branch information
shoenig authored Dec 17, 2022
1 parent 54d7ff4 commit f7a7aaf
Showing 1 changed file with 42 additions and 6 deletions.
48 changes: 42 additions & 6 deletions wait/wait.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ func boolFuncContinual(f func() bool) runnable {
ctx, cancel := context.WithDeadline(bg, r.c.deadline)
defer cancel()

timer := time.NewTimer(0)
defer timer.Stop()

for {
// make an attempt
if !f() {
Expand All @@ -167,11 +170,14 @@ func boolFuncContinual(f func() bool) runnable {
return &result{Err: nil}
}

// reset timer to gap interval
timer.Reset(r.c.gap)

// wait for gap or time
select {
case <-ctx.Done():
return &result{Err: nil}
case <-time.After(r.c.gap):
case <-timer.C:
// continue
}
}
Expand All @@ -184,6 +190,9 @@ func boolFuncInitial(f func() bool) runnable {
ctx, cancel := context.WithDeadline(bg, r.c.deadline)
defer cancel()

timer := time.NewTimer(0)
defer timer.Stop()

for {
// make an attempt
if f() {
Expand All @@ -198,11 +207,14 @@ func boolFuncInitial(f func() bool) runnable {
return &result{Err: ErrAttemptsExceeded}
}

// reset timer to gap interval
timer.Reset(r.c.gap)

// wait for gap or timeout
select {
case <-ctx.Done():
return &result{Err: ErrTimeoutExceeded}
case <-time.After(r.c.gap):
case <-timer.C:
// continue
}
}
Expand All @@ -227,6 +239,9 @@ func errFuncContinual(f func() error) runnable {
ctx, cancel := context.WithDeadline(bg, r.c.deadline)
defer cancel()

timer := time.NewTimer(0)
defer timer.Stop()

for {
// make an attempt
if err := f(); err != nil {
Expand All @@ -241,11 +256,14 @@ func errFuncContinual(f func() error) runnable {
return &result{Err: nil}
}

// reset timer to gap interval
timer.Reset(r.c.gap)

// wait for gap or time
select {
case <-ctx.Done():
return &result{Err: nil}
case <-time.After(r.c.gap):
case <-timer.C:
// continue
}
}
Expand All @@ -258,6 +276,9 @@ func errFuncInitial(f func() error) runnable {
ctx, cancel := context.WithDeadline(bg, r.c.deadline)
defer cancel()

timer := time.NewTimer(0)
defer timer.Stop()

for {
// make an attempt
err := f()
Expand All @@ -275,13 +296,16 @@ func errFuncInitial(f func() error) runnable {
}
}

// reset timer to gap interval
timer.Reset(r.c.gap)

// wait for gap or timeout
select {
case <-ctx.Done():
return &result{
Err: fmt.Errorf("%v: %w", ErrTimeoutExceeded, err),
}
case <-time.After(r.c.gap):
case <-timer.C:
// continue
}
}
Expand All @@ -307,6 +331,9 @@ func testFuncContinual(f func() (bool, error)) runnable {
ctx, cancel := context.WithDeadline(bg, r.c.deadline)
defer cancel()

timer := time.NewTimer(0)
defer timer.Stop()

for {
// make an attempt
ok, err := f()
Expand All @@ -322,11 +349,14 @@ func testFuncContinual(f func() (bool, error)) runnable {
return &result{Err: nil}
}

// reset timer to gap interval
timer.Reset(r.c.gap)

// wait for gap or time
select {
case <-ctx.Done():
return &result{Err: nil}
case <-time.After(r.c.gap):
case <-timer.C:
// continue
}
}
Expand All @@ -339,6 +369,9 @@ func testFuncInitial(f func() (bool, error)) runnable {
ctx, cancel := context.WithDeadline(bg, r.c.deadline)
defer cancel()

timer := time.NewTimer(0)
defer timer.Stop()

for {
// make an attempt
ok, err := f()
Expand All @@ -361,13 +394,16 @@ func testFuncInitial(f func() (bool, error)) runnable {
}
}

// reset timer to gap interval
timer.Reset(r.c.gap)

// wait for gap or timeout
select {
case <-ctx.Done():
return &result{
Err: fmt.Errorf("%v: %w", ErrTimeoutExceeded, err),
}
case <-time.After(r.c.gap):
case <-timer.C:
// continue
}
}
Expand Down

0 comments on commit f7a7aaf

Please sign in to comment.