-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgroup.go
More file actions
91 lines (74 loc) · 1.56 KB
/
Copy pathgroup.go
File metadata and controls
91 lines (74 loc) · 1.56 KB
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
/*
* Copyright (c) 2024-2026 Mikhail Knyazhev <markus621@yandex.com>. All rights reserved.
* Use of this source code is governed by a BSD 3-Clause license that can be found in the LICENSE file.
*/
package syncing
import (
"context"
"fmt"
"sync"
)
type (
Group interface {
Add(delta int)
Done()
Wait()
Cancel()
Background(name string, call func(ctx context.Context))
Run(name string, call func(ctx context.Context))
OnPanic(call func(err error))
}
_group struct {
wg sync.WaitGroup
mux sync.RWMutex
globalCtx context.Context
cancelCtx context.CancelFunc
onPanic func(err error)
}
)
func NewGroup(ctx context.Context) Group {
ctx, cancel := context.WithCancel(ctx)
return &_group{
globalCtx: ctx,
cancelCtx: cancel,
}
}
func (v *_group) Add(delta int) {
v.wg.Add(delta)
}
func (v *_group) Done() {
v.wg.Done()
}
func (v *_group) OnPanic(call func(err error)) {
v.mux.Lock()
defer v.mux.Unlock()
v.onPanic = call
}
func (v *_group) Wait() {
v.wg.Wait()
}
func (v *_group) Cancel() {
v.cancelCtx()
v.wg.Wait()
}
func (v *_group) Background(name string, call func(ctx context.Context)) {
v.wg.Add(1)
go v.launch(name, call)
}
func (v *_group) Run(name string, call func(ctx context.Context)) {
v.wg.Add(1)
v.launch(name, call)
}
func (v *_group) launch(name string, call func(ctx context.Context)) {
defer func() {
if err := recover(); err != nil {
v.mux.RLock()
defer v.mux.RUnlock()
if v.onPanic != nil {
v.onPanic(fmt.Errorf("%s: %v", name, err))
}
}
v.wg.Done()
}()
call(v.globalCtx)
}