github.com/haraldrudell/parl@v0.4.176/slow-detector-invocation.go (about) 1 /* 2 © 2023–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package parl 7 8 import ( 9 "strconv" 10 "strings" 11 "sync" 12 "sync/atomic" 13 "time" 14 15 "github.com/haraldrudell/parl/ptime" 16 ) 17 18 // SlowDetectorInvocation is a container used by SlowDetectorCore 19 type SlowDetectorInvocation struct { 20 sID slowID 21 threadID ThreadID 22 invoLabel string 23 t0 time.Time 24 stop func(sdi *SlowDetectorInvocation, value ...time.Time) 25 sd *SlowDetectorCore 26 27 tx atomic.Pointer[time.Time] 28 lock sync.Mutex 29 intervals []Interval 30 } 31 32 type Interval struct { 33 label string 34 t time.Time 35 } 36 37 // Stop ends an invocation part of SlowDetectorCore 38 func (sdi *SlowDetectorInvocation) Stop(value ...time.Time) { 39 sdi.stop(sdi, value...) 40 } 41 42 // Stop ends an invocation part of SlowDetectorCore 43 func (sdi *SlowDetectorInvocation) Interval(label string, t ...time.Time) { 44 var t0 time.Time 45 if len(t) > 0 { 46 t0 = t[0] 47 } 48 if t0.IsZero() { 49 t0 = time.Now() 50 } 51 52 sdi.lock.Lock() 53 defer sdi.lock.Unlock() 54 55 if label == "" { 56 label = strconv.Itoa(len(sdi.intervals) + 1) 57 } 58 sdi.intervals = append(sdi.intervals, Interval{label: label, t: t0}) 59 } 60 61 // ThreadID returns the thread ID dor the thread invoking Start 62 func (sdi *SlowDetectorInvocation) ThreadID() (threadID ThreadID) { 63 return sdi.threadID 64 } 65 66 // T0 returns the effective time of the invocation of Start 67 func (sdi *SlowDetectorInvocation) T0() (t0 time.Time) { 68 return sdi.t0 69 } 70 71 // Label returns the label for this invocation 72 func (sdi *SlowDetectorInvocation) Label() (label string) { 73 return sdi.invoLabel 74 } 75 76 // T0 returns the effective time of the invocation of Start 77 func (sdi *SlowDetectorInvocation) Time(t time.Time) (previousT time.Time) { 78 var tp *time.Time 79 if t.IsZero() { 80 tp = sdi.tx.Load() 81 } else { 82 tp = sdi.tx.Swap(&t) 83 } 84 if tp != nil { 85 previousT = *tp 86 } 87 return 88 } 89 90 func (sdi *SlowDetectorInvocation) Intervals() (intervalStr string) { 91 sdi.lock.Lock() 92 defer sdi.lock.Unlock() 93 94 if length := len(sdi.intervals); length > 0 { 95 sList := make([]string, length) 96 t0 := sdi.t0 97 for i, ivl := range sdi.intervals { 98 t := ivl.t 99 sList[i] = ptime.Duration(t.Sub(t0)) + "\x20" + ivl.label 100 t0 = t 101 } 102 intervalStr = "\x20" + strings.Join(sList, "\x20") 103 } 104 return 105 }