Showing 2 of 3 files from the diff.
Other files ignored by Codecov
options_test.go has changed.

@@ -32,15 +32,13 @@
Loading
32 32
	apply(*opts)
33 33
}
34 34
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
39 -
40 35
type opts struct {
41 -
	filters    []func(stack.Stack) bool
42 -
	maxRetries int
43 -
	maxSleep   time.Duration
36 +
	filters  []func(stack.Stack) bool
37 +
	maxSleep time.Duration
38 +
	maxRetry time.Duration
39 +
40 +
	sleep func(time.Duration)
41 +
	now   func() time.Time
44 42
}
45 43
46 44
// optionFunc lets us easily write options without a custom type.
@@ -69,6 +67,16 @@
Loading
69 67
	})
70 68
}
71 69
70 +
// MaxRetry time for the retry.
71 +
// We retry until d time if we can't find the goroutine that
72 +
// we are looking for. In between each attempt, we will sleep for
73 +
// a short while to let any running goroutines complete.
74 +
func MaxRetry(d time.Duration) Option {
75 +
	return optionFunc(func(opts *opts) {
76 +
		opts.maxRetry = d
77 +
	})
78 +
}
79 +
72 80
func maxSleep(d time.Duration) Option {
73 81
	return optionFunc(func(opts *opts) {
74 82
		opts.maxSleep = d
@@ -83,8 +91,10 @@
Loading
83 91
84 92
func buildOpts(options ...Option) *opts {
85 93
	opts := &opts{
86 -
		maxRetries: _defaultRetries,
87 -
		maxSleep:   100 * time.Millisecond,
94 +
		maxRetry: 300 * time.Millisecond,
95 +
		maxSleep: 100 * time.Millisecond,
96 +
		sleep:    time.Sleep,
97 +
		now:      time.Now,
88 98
	}
89 99
	opts.filters = append(opts.filters,
90 100
		isTestStack,
@@ -107,17 +117,30 @@
Loading
107 117
	return false
108 118
}
109 119
110 -
func (vo *opts) retry(i int) bool {
111 -
	if i >= vo.maxRetries {
112 -
		return false
113 -
	}
120 +
func (vo *opts) newRetry() func() bool {
121 +
	start := vo.now()
122 +
	sleep := 0 * time.Microsecond
123 +
124 +
	return func() bool {
125 +
		if sleep == 0 {
126 +
			sleep = time.Microsecond
127 +
			return true
128 +
		}
129 +
130 +
		if vo.now().Sub(start) >= vo.maxRetry {
131 +
			return false
132 +
		}
133 +
134 +
		vo.sleep(sleep)
114 135
115 -
	d := time.Duration(int(time.Microsecond) << uint(i))
116 -
	if d > vo.maxSleep {
117 -
		d = vo.maxSleep
136 +
		// simple backoff algorithm
137 +
		sleep *= 2
138 +
		if sleep > vo.maxSleep {
139 +
			sleep = vo.maxSleep
140 +
		}
141 +
142 +
		return true
118 143
	}
119 -
	time.Sleep(d)
120 -
	return true
121 144
}
122 145
123 146
// isTestStack is a default filter installed to automatically skip goroutines

@@ -56,14 +56,13 @@
Loading
56 56
57 57
	opts := buildOpts(options...)
58 58
	var stacks []stack.Stack
59 -
	retry := true
60 -
	for i := 0; retry; i++ {
59 +
60 +
	for retry := opts.newRetry(); retry(); {
61 61
		stacks = filterStacks(stack.All(), cur, opts)
62 62
63 63
		if len(stacks) == 0 {
64 64
			return nil
65 65
		}
66 -
		retry = opts.retry(i)
67 66
	}
68 67
69 68
	return fmt.Errorf("found unexpected goroutines:\n%s", stacks)
Files Coverage
internal/stack/stacks.go 85.42%
leaks.go 100.00%
options.go 100.00%
testmain.go 100.00%
Project Totals (4 files) 94.53%
127.1
TRAVIS_OS_NAME=linux
1.12.x=.12.x
127.3
1.14.x=.14.x
TRAVIS_OS_NAME=linux

No yaml found.

Create your codecov.yml to customize your Codecov experience

Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading