pkg/{timex,wait}: Unify code
This commit is contained in:
parent
59fff07b59
commit
8701fab93b
10 changed files with 77 additions and 74 deletions
|
|
@ -1,3 +1,4 @@
|
|||
// Package timex provides Interval and Wait
|
||||
package timex
|
||||
|
||||
import (
|
||||
|
|
@ -5,21 +6,49 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// SetInterval invokes f with the current time and then spawns a new goroutine that runs f every d, until context is closed.
|
||||
func SetInterval(ctx context.Context, d time.Duration, f func(t time.Time)) {
|
||||
f(time.Now())
|
||||
// TickContext is like [time.Tick], but closes the returned channel once the context closes.
|
||||
// As such it can be recovered by the garbage collector; see [time.TickContext].
|
||||
//
|
||||
// Unlike [time.Tick], immediatly send the current time on the given channel.
|
||||
func TickContext(c context.Context, d time.Duration) <-chan time.Time {
|
||||
if d < 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
timer := make(chan time.Time, 1)
|
||||
timer <- time.Now()
|
||||
go func() {
|
||||
t := time.NewTicker(d)
|
||||
defer t.Stop()
|
||||
defer close(timer)
|
||||
|
||||
for {
|
||||
select {
|
||||
case tick := <-t.C:
|
||||
f(tick)
|
||||
case <-ctx.Done():
|
||||
timer <- tick
|
||||
case <-c.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}()
|
||||
return timer
|
||||
}
|
||||
|
||||
// TickUntilFunc invokes f every d until either context is closed, or f returns true.
|
||||
// f is invoked once immediatly when the timer starts.
|
||||
//
|
||||
// TickUntilFunc blocks until f is no longer invoked.
|
||||
//
|
||||
// Returns the error of the context (if any).
|
||||
func TickUntilFunc(f func(t time.Time) bool, c context.Context, d time.Duration) error {
|
||||
context, cancel := context.WithCancel(c)
|
||||
defer cancel()
|
||||
|
||||
for t := range TickContext(context, d) {
|
||||
if f(t) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return c.Err()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
package wait
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Wait repeatedly invokes f, until it returns true or the context is closed.
|
||||
// The invocation interval is determined by interval.
|
||||
func Wait(f func() bool, interval time.Duration, context context.Context) error {
|
||||
// create a new timer
|
||||
timer := time.NewTimer(interval)
|
||||
if !timer.Stop() {
|
||||
<-timer.C
|
||||
}
|
||||
defer timer.Stop()
|
||||
|
||||
for {
|
||||
if f() {
|
||||
return nil
|
||||
}
|
||||
|
||||
// reset the timer, and wait for it again!
|
||||
timer.Reset(interval)
|
||||
select {
|
||||
case <-timer.C:
|
||||
case <-context.Done():
|
||||
return context.Err()
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue