21
21
package goleak
22
22
23
23
import (
24
+ "errors"
24
25
"strings"
25
26
"time"
26
27
@@ -32,10 +33,14 @@ type Option interface {
32
33
apply (* opts )
33
34
}
34
35
35
- // We retry up to 20 times if we can't find the goroutine that
36
- // we are looking for. In between each attempt, we will sleep for
37
- // a short while to let any running goroutines complete.
38
- const _defaultRetries = 20
36
+ const (
37
+ // We retry up to default 20 times if we can't find the goroutine that
38
+ // we are looking for.
39
+ _defaultRetryAttempts = 20
40
+ // In between each retry attempt, sleep for up to default 100 microseconds
41
+ // to let any running goroutine completes.
42
+ _defaultSleepInterval = 100 * time .Microsecond
43
+ )
39
44
40
45
type opts struct {
41
46
filters []func (stack.Stack ) bool
@@ -53,6 +58,17 @@ func (o *opts) apply(opts *opts) {
53
58
opts .cleanup = o .cleanup
54
59
}
55
60
61
+ // validate the options.
62
+ func (o * opts ) validate () error {
63
+ if o .maxRetries < 0 {
64
+ return errors .New ("maxRetryAttempts should be greater than 0" )
65
+ }
66
+ if o .maxSleep <= 0 {
67
+ return errors .New ("maxSleepInterval should be greater than 0s" )
68
+ }
69
+ return nil
70
+ }
71
+
56
72
// optionFunc lets us easily write options without a custom type.
57
73
type optionFunc func (* opts )
58
74
@@ -91,12 +107,25 @@ func IgnoreCurrent() Option {
91
107
})
92
108
}
93
109
94
- func maxSleep (d time.Duration ) Option {
110
+ // MaxSleepInterval sets the maximum sleep time in-between each retry attempt.
111
+ // The sleep duration grows in an exponential backoff, to a maximum of the value specified here.
112
+ // If not configured, default to 100 microseconds.
113
+ func MaxSleepInterval (d time.Duration ) Option {
95
114
return optionFunc (func (opts * opts ) {
96
115
opts .maxSleep = d
97
116
})
98
117
}
99
118
119
+ // MaxRetryAttempts sets the retry upper limit.
120
+ // When finding extra goroutines, we'll retry until all goroutines complete
121
+ // or end up with the maximum retry attempts.
122
+ // If not configured, default to 20 times.
123
+ func MaxRetryAttempts (num int ) Option {
124
+ return optionFunc (func (opts * opts ) {
125
+ opts .maxRetries = num
126
+ })
127
+ }
128
+
100
129
func addFilter (f func (stack.Stack ) bool ) Option {
101
130
return optionFunc (func (opts * opts ) {
102
131
opts .filters = append (opts .filters , f )
@@ -105,8 +134,8 @@ func addFilter(f func(stack.Stack) bool) Option {
105
134
106
135
func buildOpts (options ... Option ) * opts {
107
136
opts := & opts {
108
- maxRetries : _defaultRetries ,
109
- maxSleep : 100 * time . Millisecond ,
137
+ maxRetries : _defaultRetryAttempts ,
138
+ maxSleep : _defaultSleepInterval ,
110
139
}
111
140
opts .filters = append (opts .filters ,
112
141
isTestStack ,
@@ -117,6 +146,7 @@ func buildOpts(options ...Option) *opts {
117
146
for _ , option := range options {
118
147
option .apply (opts )
119
148
}
149
+
120
150
return opts
121
151
}
122
152
0 commit comments