-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgroup.go
48 lines (40 loc) · 1.39 KB
/
group.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
package gogroup
import (
"context"
"slices"
"sync"
"github.com/newmo-oss/gogroup/internal"
)
// Group is a group of goroutines used to run functions concurrently.
// Functions are registered with [(*Group).Add].
// [(*Group).Run] calls each functions in different goroutines and waits for the functions to finish.
// If a panic occurs in a function, Run recovers the panic and returns it as an error.
// If any function returns non nil error, the context is canceled.
type Group struct {
mu sync.Mutex
funcs []func(context.Context) error
}
// Add adds a function to the group.
func (g *Group) Add(f func(context.Context) error) {
g.mu.Lock()
g.funcs = append(g.funcs, f)
g.mu.Unlock()
}
func (g *Group) start(ctx context.Context) func() error {
g.mu.Lock()
funcs := slices.Clone(g.funcs)
g.mu.Unlock()
return internal.Start(ctx, funcs)
}
// Run calls all registered functions in different goroutines.
func (g *Group) Run(ctx context.Context) error {
return g.start(ctx)()
}
// Start calls the function in new goroutine and returns a wait function.
// When the wait function is called, it waits for the goroutine and returns the returned value of the function.
// If a panic occurs in the function, the wait function recovers the panic and returns it as an error.
func Start(ctx context.Context, f func(context.Context) error) (wait func() error) {
var g Group
g.Add(f)
return g.start(ctx)
}