-
Notifications
You must be signed in to change notification settings - Fork 1
/
slow-detector-invocation.go
105 lines (89 loc) · 2.25 KB
/
slow-detector-invocation.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
/*
© 2023–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
ISC License
*/
package parl
import (
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/haraldrudell/parl/ptime"
)
// SlowDetectorInvocation is a container used by SlowDetectorCore
type SlowDetectorInvocation struct {
sID slowID
threadID ThreadID
invoLabel string
t0 time.Time
stop func(sdi *SlowDetectorInvocation, value ...time.Time)
sd *SlowDetectorCore
tx atomic.Pointer[time.Time]
lock sync.Mutex
intervals []Interval
}
type Interval struct {
label string
t time.Time
}
// Stop ends an invocation part of SlowDetectorCore
func (sdi *SlowDetectorInvocation) Stop(value ...time.Time) {
sdi.stop(sdi, value...)
}
// Stop ends an invocation part of SlowDetectorCore
func (sdi *SlowDetectorInvocation) Interval(label string, t ...time.Time) {
var t0 time.Time
if len(t) > 0 {
t0 = t[0]
}
if t0.IsZero() {
t0 = time.Now()
}
sdi.lock.Lock()
defer sdi.lock.Unlock()
if label == "" {
label = strconv.Itoa(len(sdi.intervals) + 1)
}
sdi.intervals = append(sdi.intervals, Interval{label: label, t: t0})
}
// ThreadID returns the thread ID dor the thread invoking Start
func (sdi *SlowDetectorInvocation) ThreadID() (threadID ThreadID) {
return sdi.threadID
}
// T0 returns the effective time of the invocation of Start
func (sdi *SlowDetectorInvocation) T0() (t0 time.Time) {
return sdi.t0
}
// Label returns the label for this invocation
func (sdi *SlowDetectorInvocation) Label() (label string) {
return sdi.invoLabel
}
// T0 returns the effective time of the invocation of Start
func (sdi *SlowDetectorInvocation) Time(t time.Time) (previousT time.Time) {
var tp *time.Time
if t.IsZero() {
tp = sdi.tx.Load()
} else {
tp = sdi.tx.Swap(&t)
}
if tp != nil {
previousT = *tp
}
return
}
func (sdi *SlowDetectorInvocation) Intervals() (intervalStr string) {
sdi.lock.Lock()
defer sdi.lock.Unlock()
if length := len(sdi.intervals); length > 0 {
sList := make([]string, length)
t0 := sdi.t0
for i, ivl := range sdi.intervals {
t := ivl.t
sList[i] = ptime.Duration(t.Sub(t0)) + "\x20" + ivl.label
t0 = t
}
intervalStr = "\x20" + strings.Join(sList, "\x20")
}
return
}