/
if-counter.go
187 lines (169 loc) · 7.63 KB
/
if-counter.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
© 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
ISC License
*/
package parl
import (
"fmt"
"time"
)
// CounterID is a unique type containing counter names
type CounterID string
// data provider side
// Counters is the data provider interface for a counter set.
// - max and running values are offered
// - Counters and datapointy are thread-safe
// - counters may be used to determine that code abide
// by intended paralellism and identifying hangs or abnormalisms.
// - Printing counters every second can verify adequate progress and
// possibly identify blocking of threads or swapping and garbage collection
// outages.
type Counters interface {
// GetOrCreateCounter is used by the data provider of a counter.
// - A counter has Inc and Dec operations.
// - Counters can be used to track number of currently operating invocations.
// - if period is present and positive, the counter created is a RateCounter.
// Rate counters use threads, one per distinct period requested.
// Rate counter threads are monitored by the provided Go group and failure
// may force a counter restart or cause application termination. Failures
// are typically caused by panics in the counter update task.
// - Counter is the data-provider side of a counter
// - CounterValues is the consumer side of a counter
GetOrCreateCounter(name CounterID, period ...time.Duration) (counter Counter)
// GetOrCreateCounter is used by the data provider of a datapoint.
// A datapoint supports SetValue operation.
// A datapoint tracks a quantity such as a latency value.
GetOrCreateDatapoint(name CounterID, period time.Duration) (datapoint Datapoint)
}
// CounterSetData provides simple access to a set of counters, rate counters and datapoints/
type CounterSetData interface {
Exists(name CounterID) (exists bool)
// Value returns the monotonically increasing value for a possible plain counter
// - if no such counter exists, 0
Value(name CounterID) (value uint64)
// Running returns the increasing and decreasing running value for a possible plain counter
// - if no such counter exists, 0
Get(name CounterID) (value, running, max uint64)
// Rates returns the rate values a possible rate counter
// - if no such counter exists or values are not yet available, nil
Rates(name CounterID) (rates map[RateType]float64)
// DatapointValue returns the latest value a possible datapoint
// - if no such datapoint exists, 0
DatapointValue(name CounterID) (value uint64)
// DatapointMax returns the highest seen value for a possible datapoint
// - if no such datapoint exists, 0
DatapointMax(name CounterID) (max uint64)
// DatapointMin returns the lowest seen value for a possible datapoint
// - if no such datapoint exists, 0
DatapointMin(name CounterID) (min uint64)
// GetDatapoint returns dfatapoint data for a possible datapoint
// - if no such datapoint exists, 0
GetDatapoint(name CounterID) (value, max, min uint64, isValid bool, average float64, n uint64)
}
// Counter is the data provider interface for a counter
// - Inc Dec Add operations, Thread-safe
type Counter interface {
// Inc increments the counter. Thread-Safe, method chaining
Inc() (counter Counter)
// Dec decrements the counter but not below zero. Thread-Safe, method chaining
Dec() (counter Counter)
// Add adds a positive or negative delta. Thread-Safe, method chaining
Add(delta int64) (counter Counter)
}
// Datapoint tracks a value with average, max-min, and increase/decrease rates.
type Datapoint interface {
// SetValue records a value at time.Now().
// SetValue supports method chaining.
SetValue(value uint64) (datapoint Datapoint)
}
// consumer side
// CounterSet is the consumer interface for a counter set
type CounterSet interface {
// GetCounters gets a list and a map for consuming counter data
GetCounters() (orderedKeys []CounterID, m map[CounterID]any)
// ResetCounters resets all counters to their initial state
ResetCounters(stopRateCounters bool)
}
// CounterStore is a CounterSet consumer interface facilitating caching
type CounterStore interface {
// GetOrCreateCounter retrieves a regular counter
// - never returns nil
// - type asserted to CounterValues
GetCounter(name CounterID) (counter Counter)
//GetCounter retrieves a counter that must exist
// - may return nil
// - type asserted to RateCounterValues or DatapointValue
GetNamedCounter(name CounterID) (counter any)
}
// CounterValues is the consumer interface for a counter. Thread-safe
type CounterValues interface {
// Get returns value/running/max with integrity. Thread-Safe
// - value is the monotonically increasing value
// - running is the fluctuating running value
// - max is the highest value running has had
Get() (value, running, max uint64)
// GetReset returns value/running/max with integrity and resets the counter. Thread-Safe
// - value is the monotonically increasing value
// - running is the fluctuating running value
// - max is the highest value running has had
GetReset() (value, running, max uint64)
// Value returns the monotonically increasing value. Thread-Safe
// - number of Inc invocations and positive Adds
Value() (value uint64)
// Running returns the fluctuating running value. Thread-Safe
// - number of Inc less Dec invocations and sum of Adds
// - never below 0
Running() (running uint64)
// Max returns the highest value running has had. Thread-Safe
Max() (max uint64)
}
// CounterValues is the consumer interface for a rate counter.
// The rate counter provides rates over a provided time period in a map of int64 values.
// - ValueRate current rate of increase in value
// - ValueMaxRate the maxmimum seen rate of increase in value
// - ValueRateAverage the average rate of increase in value taken over up to 10 periods
// - RunningRate the current rate of change in running, may be negative
// - RunningMaxRate the max positive rate of increase seen in running
// - RunningMaxDecRate the max rate of decrease in running, a 0 or negative value
// - RunningAverage the average of running taken over up to 10 periods
type RateCounterValues interface {
CounterValues // Get() GetReset() Value() Running() Max()
Rates() (rates map[RateType]float64)
}
// Rate describes a rate datapoint.
// - may be positive or negative
type Rate interface {
Clone() (rate Rate)
Delta() (delta uint64)
Duration() (duration time.Duration)
HasValue() (hasValue bool)
fmt.Stringer
}
type DatapointValue interface {
CloneDatapoint() (datapoint Datapoint) // Clone takes a snapshot of a counter state.
CloneDatapointReset() (datapoint Datapoint) // CloneReset takes a snapshot of a counter state and resets it to its initial state.
GetDatapoint() (value, max, min uint64, isValid bool, average float64, n uint64)
DatapointValue() (value uint64)
DatapointMax() (max uint64)
DatapointMin() (min uint64)
}
// CountersFactory is an abstract counter factory.
// CountersFactory enables providing of different counter implementations.
type CountersFactory interface {
// NewCounters returns a counter container.
// is useCounters is false, the container does not actually do any counting.
NewCounters(useCounters bool, g0 GoGen) (counters Counters)
}
const (
ValueRate RateType = iota // current rate of increase in value
ValueMaxRate // max seen rate of increase in value
ValueRateAverage // average rate of increase in value during last 10 periods
RunningRate
RunningMaxRate
RunningMaxDecRate
// accumulated change in running over several intervals
// - running value goes up and down
RunningAverage
NotAValue // NotAValue is an internal stand-in value indicating a value not in use
)
type RateType int