-
Notifications
You must be signed in to change notification settings - Fork 0
/
parallel.go
107 lines (96 loc) · 3.85 KB
/
parallel.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package async
import (
"context"
)
// Parallel runs the functions asynchronously with the specified concurrency limitation. It will
// send a cancel sign to context and terminate immediately if any function returns an error or
// panic, and also returns an execution error to indicate the error.
//
// The number of concurrency must be greater than or equal to 0, and it means no concurrency
// limitation if the number is 0.
//
// // Run 2 functions asynchronously at the time.
// out, err := async.Parallel(2, func(ctx context.Context) (int, error) {
// // Do something
// return 1, nil
// }, func(ctx context.Context) (string, error) {
// // Do something
// return "hello", nil
// }, func(ctx context.Context) error {
// // Do something
// return nil
// } /* , ... */)
// // out: [][]any{{1, <nil>}, {"hello", <nil>}, {<nil>}}
// // err: <nil>
func Parallel(concurrency int, funcs ...AsyncFn) ([][]any, error) {
return parallel(context.Background(), concurrency, funcs...)
}
// ParallelWithContext runs the functions asynchronously with the specified concurrency limitation.
// It will send a cancel sign to context and terminate immediately if any function returns an error
// or panic, and also returns an execution error to indicate the error. If the context was canceled
// or timed out before all functions finished executing, it will send a cancel sign to all
// uncompleted functions, and return a context canceled error.
//
// The number of concurrency must be greater than or equal to 0, and it means no concurrency
// limitation if the number is 0.
func ParallelWithContext(
ctx context.Context,
concurrency int,
funcs ...AsyncFn,
) ([][]any, error) {
return parallel(ctx, concurrency, funcs...)
}
// parallel runs the functions asynchronously with the specified concurrency.
func parallel(parent context.Context, concurrency int, funcs ...AsyncFn) ([][]any, error) {
paralleler := builtinPool.Get().(*Paralleler)
defer func() {
builtinPool.Put(paralleler)
}()
paralleler.
WithContext(parent).
WithConcurrency(concurrency).
Add(funcs...)
return paralleler.Run()
}
// ParallelCompleted runs the functions asynchronously with the specified concurrency limitation.
// It returns an error array and a boolean value to indicate whether any function panics or returns
// an error, and you can get the error details from the error array by the indices of the functions
// in the parameter list. It will return until all of the functions are finished.
//
// The number of concurrency must be greater than or equal to 0, and it means no concurrency
// limitation if the number is 0.
func ParallelCompleted(concurrency int, funcs ...AsyncFn) ([][]any, error) {
return parallelCompleted(context.Background(), concurrency, funcs...)
}
// ParallelCompletedWithContext runs the functions asynchronously with the specified concurrency
// limitation and the context. It returns an error array and a boolean value to indicate whether
// any function panics or returns an error, and you can get the error details from the error array
// by the indices of the functions in the parameter list. It will return until all of the functions
// are finished.
//
// The number of concurrency must be greater than or equal to 0, and it means no concurrency
// limitation if the number is 0.
func ParallelCompletedWithContext(
ctx context.Context,
concurrency int,
funcs ...AsyncFn,
) ([][]any, error) {
return parallelCompleted(ctx, concurrency, funcs...)
}
// parallelCompleted runs the functions asynchronously with the specified concurrency until all of
// the functions are finished.
func parallelCompleted(
parent context.Context,
concurrency int,
funcs ...AsyncFn,
) ([][]any, error) {
paralleler := builtinPool.Get().(*Paralleler)
defer func() {
builtinPool.Put(paralleler)
}()
paralleler.
WithContext(parent).
WithConcurrency(concurrency).
Add(funcs...)
return paralleler.RunCompleted()
}