-
Notifications
You must be signed in to change notification settings - Fork 1
/
trace-group.go
71 lines (59 loc) · 1.31 KB
/
trace-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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/*
© 2021–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
ISC License
*/
package parl
import (
"strings"
"sync"
)
const (
maxList = 100
skipFrames = 2
)
// parl.TraceGroup is an observable sync.Waitgroup.
//
// TraceGroup cannot be in parl because WaitAction imports goid
type TraceGroup struct {
WaitGroup
lock sync.Mutex
list []WaitAction // behind lock
}
func (wg *TraceGroup) Add(delta int) {
wg.WaitGroup.Add(delta)
wg.action(delta, false)
}
func (wg *TraceGroup) Done() {
wg.WaitGroup.Done()
wg.action(0, true)
}
func (wg *TraceGroup) DoneBool() (isZero bool) {
isZero = wg.WaitGroup.DoneBool()
wg.action(0, true)
return
}
func (wg *TraceGroup) action(delta int, isDone bool) {
wg.lock.Lock()
defer wg.lock.Unlock()
if len(wg.list) == maxList {
copy(wg.list, wg.list[1:])
}
wg.list = append(wg.list, *NewWaitAction(skipFrames, delta, isDone))
}
func (wg *TraceGroup) String() (s string) {
adds, dones := wg.WaitGroup.Counters()
s = Sprintf("%d(%d)", dones, adds)
wg.lock.Lock()
defer wg.lock.Unlock()
if len(wg.list) == 0 {
return
}
if len(wg.list) == 1 {
return s + "\x20" + wg.list[0].String()
}
sL := make([]string, len(wg.list))
for i, action := range wg.list {
sL[i] = action.String()
}
return s + ":\n" + strings.Join(sL, "\n")
}