Skip to content

Commit 995000d

Browse files
authored
Add WithFailFast() (#118)
In #104, a "FailFast" option is likely going to be added to iterators that, on error, stops running additional tasks and returns the error that caused the first failure. "FailFast" seems is a pretty standard description for this behavior, and combining two common options into a single option with a more discoverable name seems like a nice thing to do before 1.0.
1 parent 8e5ba59 commit 995000d

File tree

4 files changed

+37
-2
lines changed

4 files changed

+37
-2
lines changed

pool/context_pool.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ func (p *ContextPool) WithCancelOnError() *ContextPool {
8181
return p
8282
}
8383

84+
// WithFailFast is an alias for the combination of WithFirstError and
85+
// WithCancelOnError. By default, the errors from all tasks are returned and
86+
// the pool's context is not canceled until the parent context is canceled.
87+
func (p *ContextPool) WithFailFast() *ContextPool {
88+
p.panicIfInitialized()
89+
p.WithFirstError()
90+
p.WithCancelOnError()
91+
return p
92+
}
93+
8494
// WithMaxGoroutines limits the number of goroutines in a pool.
8595
// Defaults to unlimited. Panics if n < 1.
8696
func (p *ContextPool) WithMaxGoroutines(n int) *ContextPool {

pool/context_pool_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,9 @@ func TestContextPool(t *testing.T) {
187187
require.NotErrorIs(t, err, err2)
188188
})
189189

190-
t.Run("WithFirstError and WithCancelOnError", func(t *testing.T) {
190+
t.Run("WithFailFast", func(t *testing.T) {
191191
t.Parallel()
192-
p := New().WithContext(bgctx).WithFirstError().WithCancelOnError()
192+
p := New().WithContext(bgctx).WithFailFast()
193193
p.Go(func(ctx context.Context) error {
194194
return err1
195195
})

pool/result_context_pool.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ func (p *ResultContextPool[T]) WithCancelOnError() *ResultContextPool[T] {
6262
return p
6363
}
6464

65+
// WithFailFast is an alias for the combination of WithFirstError and
66+
// WithCancelOnError. By default, the errors from all tasks are returned and
67+
// the pool's context is not canceled until the parent context is canceled.
68+
func (p *ResultContextPool[T]) WithFailFast() *ResultContextPool[T] {
69+
p.panicIfInitialized()
70+
p.contextPool.WithFailFast()
71+
return p
72+
}
73+
6574
// WithMaxGoroutines limits the number of goroutines in a pool.
6675
// Defaults to unlimited. Panics if n < 1.
6776
func (p *ResultContextPool[T]) WithMaxGoroutines(n int) *ResultContextPool[T] {

pool/result_context_pool_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,22 @@ func TestResultContextPool(t *testing.T) {
101101
require.ErrorIs(t, err, err1)
102102
})
103103

104+
t.Run("WithFailFast", func(t *testing.T) {
105+
t.Parallel()
106+
p := NewWithResults[int]().WithContext(context.Background()).WithFailFast()
107+
p.Go(func(ctx context.Context) (int, error) {
108+
return 0, err1
109+
})
110+
p.Go(func(ctx context.Context) (int, error) {
111+
<-ctx.Done()
112+
return 1, ctx.Err()
113+
})
114+
results, err := p.Wait()
115+
require.ErrorIs(t, err, err1)
116+
require.NotErrorIs(t, err, context.Canceled)
117+
require.Empty(t, results)
118+
})
119+
104120
t.Run("WithCancelOnError and panic", func(t *testing.T) {
105121
t.Parallel()
106122
p := NewWithResults[int]().

0 commit comments

Comments
 (0)