Skip to content

Commit f58ac88

Browse files
committed
clean non-working propogation of cancel back to caller, invert it to traditional termination
1 parent 350e367 commit f58ac88

File tree

2 files changed

+25
-14
lines changed

2 files changed

+25
-14
lines changed

errsizedgroup.go

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ type ErrSizedGroup struct {
2020
}
2121

2222
// NewErrSizedGroup makes wait group with limited size alive goroutines.
23-
// By default all goroutines will be started but will wait inside. For limited number of goroutines use Preemptive() options.
23+
// By default, all goroutines will be started but will wait inside.
24+
// For limited number of goroutines use Preemptive() options.
2425
// TermOnErr will skip (won't start) all other goroutines if any error returned.
2526
func NewErrSizedGroup(size int, options ...GroupOption) *ErrSizedGroup {
2627
res := ErrSizedGroup{
@@ -39,6 +40,27 @@ func NewErrSizedGroup(size int, options ...GroupOption) *ErrSizedGroup {
3940
// The first call to return a non-nil error cancels the group if termOnError; its error will be
4041
// returned by Wait. If no termOnError all errors will be collected in multierror.
4142
func (g *ErrSizedGroup) Go(f func() error) {
43+
44+
canceled := func() bool {
45+
if g.ctx == nil {
46+
return false
47+
}
48+
select {
49+
case <-g.ctx.Done():
50+
return true
51+
default:
52+
return false
53+
}
54+
}
55+
56+
if canceled() {
57+
g.errOnce.Do(func() {
58+
// don't repeat this error
59+
g.err.append(g.ctx.Err())
60+
})
61+
return
62+
}
63+
4264
g.wg.Add(1)
4365

4466
isLocked := false
@@ -87,16 +109,9 @@ func (g *ErrSizedGroup) Go(f func() error) {
87109
}
88110

89111
if err := f(); err != nil {
90-
91112
g.errLock.Lock()
92113
g.err = g.err.append(err)
93114
g.errLock.Unlock()
94-
95-
g.errOnce.Do(func() { // call context cancel once
96-
if g.cancel != nil {
97-
g.cancel()
98-
}
99-
})
100115
}
101116
}()
102117
}
@@ -105,9 +120,6 @@ func (g *ErrSizedGroup) Go(f func() error) {
105120
// returns all errors (if any) wrapped with multierror from them.
106121
func (g *ErrSizedGroup) Wait() error {
107122
g.wg.Wait()
108-
if g.cancel != nil {
109-
g.cancel()
110-
}
111123
return g.err.errorOrNil()
112124
}
113125

group_options.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import "context"
44

55
type options struct {
66
ctx context.Context
7-
cancel context.CancelFunc
87
preLock bool
98
termOnError bool
109
discardIfFull bool
@@ -13,10 +12,10 @@ type options struct {
1312
// GroupOption functional option type
1413
type GroupOption func(o *options)
1514

16-
// Context passes ctx and makes it cancelable
15+
// Context passes ctx to group, goroutines will be canceled if ctx is canceled
1716
func Context(ctx context.Context) GroupOption {
1817
return func(o *options) {
19-
o.ctx, o.cancel = context.WithCancel(ctx)
18+
o.ctx = ctx
2019
}
2120
}
2221

0 commit comments

Comments
 (0)