-
Notifications
You must be signed in to change notification settings - Fork 0
/
wait.go
80 lines (69 loc) · 1.85 KB
/
wait.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package wait
import (
"context"
"time"
)
const (
// DefaultTimeout is the default max time to wait before returning an error if a timeout is not provided
DefaultTimeout = 30 * time.Minute
// DefaultInterval is the polling interval to use if an interval is not provided
DefaultInterval = 10 * time.Second
)
// Options are the options available when waiting
type Options struct {
Context context.Context
Interval time.Duration
Timeout time.Duration
}
// Option is a function that can be optionally provided to override default options of a wait condition
type Option func(*Options)
// WithTimeout overrides the default timeout when waiting
func WithTimeout(timeout time.Duration) Option {
return func(options *Options) {
options.Timeout = timeout
}
}
// WithInterval overrides the default polling interval when waiting
func WithInterval(interval time.Duration) Option {
return func(options *Options) {
options.Interval = interval
}
}
// WithContext overrides the context used when waiting.
// This allows for using a context with a timeout / deadline already set.
func WithContext(context context.Context) Option {
return func(options *Options) {
options.Context = context
}
}
// For continuously polls the provided WaitCondition function until either
// the timeout is reached or the function returns as done
func For(fn WaitCondition, opts ...Option) error {
options := &Options{
Context: context.Background(),
Interval: DefaultInterval,
Timeout: DefaultTimeout,
}
for _, optFn := range opts {
optFn(options)
}
ctx, cancel := context.WithTimeout(options.Context, options.Timeout)
defer cancel()
for {
select {
case <-ctx.Done():
// Timeout / deadline reached
return ctx.Err()
default:
done, err := fn()
if err != nil {
return err
}
if !done {
time.Sleep(options.Interval)
continue
}
return nil
}
}
}