github.com/haraldrudell/parl@v0.4.176/if-counter.go (about)

     1  /*
     2  © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package parl
     7  
     8  import (
     9  	"fmt"
    10  	"time"
    11  )
    12  
    13  // CounterID is a unique type containing counter names
    14  type CounterID string
    15  
    16  // data provider side
    17  
    18  // Counters is the data provider interface for a counter set.
    19  //   - max and running values are offered
    20  //   - Counters and datapointy are thread-safe
    21  //   - counters may be used to determine that code abide
    22  //     by intended paralellism and identifying hangs or abnormalisms.
    23  //   - Printing counters every second can verify adequate progress and
    24  //     possibly identify blocking of threads or swapping and garbage collection
    25  //     outages.
    26  type Counters interface {
    27  	// GetOrCreateCounter is used by the data provider of a counter.
    28  	//	- A counter has Inc and Dec operations.
    29  	//	- Counters can be used to track number of currently operating invocations.
    30  	//	- if period is present and positive, the counter created is a RateCounter.
    31  	// Rate counters use threads, one per distinct period requested.
    32  	// Rate counter threads are monitored by the provided Go group and failure
    33  	// may force a counter restart or cause application termination. Failures
    34  	// are typically caused by panics in the counter update task.
    35  	//	- Counter is the data-provider side of a counter
    36  	//	- CounterValues is the consumer side of a counter
    37  	GetOrCreateCounter(name CounterID, period ...time.Duration) (counter Counter)
    38  	// GetOrCreateCounter is used by the data provider of a datapoint.
    39  	// A datapoint supports SetValue operation.
    40  	// A datapoint tracks a quantity such as a latency value.
    41  	GetOrCreateDatapoint(name CounterID, period time.Duration) (datapoint Datapoint)
    42  }
    43  
    44  // CounterSetData provides simple access to a set of counters, rate counters and datapoints/
    45  type CounterSetData interface {
    46  	Exists(name CounterID) (exists bool)
    47  	// Value returns the monotonically increasing value for a possible plain counter
    48  	//	- if no such counter exists, 0
    49  	Value(name CounterID) (value uint64)
    50  	// Running returns the increasing and decreasing running value for a possible plain counter
    51  	//	- if no such counter exists, 0
    52  	Get(name CounterID) (value, running, max uint64)
    53  	// Rates returns the rate values a possible rate counter
    54  	//	- if no such counter exists or values are not yet available, nil
    55  	Rates(name CounterID) (rates map[RateType]float64)
    56  	// DatapointValue returns the latest value a possible datapoint
    57  	//	- if no such datapoint exists, 0
    58  	DatapointValue(name CounterID) (value uint64)
    59  	// DatapointMax returns the highest seen value for a possible datapoint
    60  	//	- if no such datapoint exists, 0
    61  	DatapointMax(name CounterID) (max uint64)
    62  	// DatapointMin returns the lowest seen value for a possible datapoint
    63  	//	- if no such datapoint exists, 0
    64  	DatapointMin(name CounterID) (min uint64)
    65  	// GetDatapoint returns dfatapoint data for a possible datapoint
    66  	//	- if no such datapoint exists, 0
    67  	GetDatapoint(name CounterID) (value, max, min uint64, isValid bool, average float64, n uint64)
    68  }
    69  
    70  // Counter is the data provider interface for a counter
    71  //   - Inc Dec Add operations, Thread-safe
    72  type Counter interface {
    73  	// Inc increments the counter. Thread-Safe, method chaining
    74  	Inc() (counter Counter)
    75  	// Dec decrements the counter but not below zero. Thread-Safe, method chaining
    76  	Dec() (counter Counter)
    77  	// Add adds a positive or negative delta. Thread-Safe, method chaining
    78  	Add(delta int64) (counter Counter)
    79  }
    80  
    81  // Datapoint tracks a value with average, max-min, and increase/decrease rates.
    82  type Datapoint interface {
    83  	// SetValue records a value at time.Now().
    84  	// SetValue supports method chaining.
    85  	SetValue(value uint64) (datapoint Datapoint)
    86  }
    87  
    88  // consumer side
    89  
    90  // CounterSet is the consumer interface for a counter set
    91  type CounterSet interface {
    92  	// GetCounters gets a list and a map for consuming counter data
    93  	GetCounters() (orderedKeys []CounterID, m map[CounterID]any)
    94  	// ResetCounters resets all counters to their initial state
    95  	ResetCounters(stopRateCounters bool)
    96  }
    97  
    98  // CounterStore is a CounterSet consumer interface facilitating caching
    99  type CounterStore interface {
   100  	// GetOrCreateCounter retrieves a regular counter
   101  	//	- never returns nil
   102  	//	- type asserted to CounterValues
   103  	GetCounter(name CounterID) (counter Counter)
   104  	//GetCounter retrieves a counter that must exist
   105  	//	- may return nil
   106  	//	- type asserted to RateCounterValues or DatapointValue
   107  	GetNamedCounter(name CounterID) (counter any)
   108  }
   109  
   110  // CounterValues is the consumer interface for a counter. Thread-safe
   111  type CounterValues interface {
   112  	// Get returns value/running/max with integrity. Thread-Safe
   113  	//	- value is the monotonically increasing value
   114  	//	- running is the fluctuating running value
   115  	//	- max is the highest value running has had
   116  	Get() (value, running, max uint64)
   117  	// GetReset returns value/running/max with integrity and resets the counter. Thread-Safe
   118  	//	- value is the monotonically increasing value
   119  	//	- running is the fluctuating running value
   120  	//	- max is the highest value running has had
   121  	GetReset() (value, running, max uint64)
   122  	// Value returns the monotonically increasing value. Thread-Safe
   123  	//	- number of Inc invocations and positive Adds
   124  	Value() (value uint64)
   125  	// Running returns the fluctuating running value. Thread-Safe
   126  	//	- number of Inc less Dec invocations and sum of Adds
   127  	//	- never below 0
   128  	Running() (running uint64)
   129  	// Max returns the highest value running has had. Thread-Safe
   130  	Max() (max uint64)
   131  }
   132  
   133  // CounterValues is the consumer interface for a rate counter.
   134  // The rate counter provides rates over a provided time period in a map of int64 values.
   135  //   - ValueRate current rate of increase in value
   136  //   - ValueMaxRate the maxmimum seen rate of increase in value
   137  //   - ValueRateAverage the average rate of increase in value taken over up to 10 periods
   138  //   - RunningRate the current rate of change in running, may be negative
   139  //   - RunningMaxRate the max positive rate of increase seen in running
   140  //   - RunningMaxDecRate the max rate of decrease in running, a 0 or negative value
   141  //   - RunningAverage the average of running taken over up to 10 periods
   142  type RateCounterValues interface {
   143  	CounterValues // Get() GetReset() Value() Running() Max()
   144  	Rates() (rates map[RateType]float64)
   145  }
   146  
   147  // Rate describes a rate datapoint.
   148  //   - may be positive or negative
   149  type Rate interface {
   150  	Clone() (rate Rate)
   151  	Delta() (delta uint64)
   152  	Duration() (duration time.Duration)
   153  	HasValue() (hasValue bool)
   154  	fmt.Stringer
   155  }
   156  
   157  type DatapointValue interface {
   158  	CloneDatapoint() (datapoint Datapoint)      // Clone takes a snapshot of a counter state.
   159  	CloneDatapointReset() (datapoint Datapoint) // CloneReset takes a snapshot of a counter state and resets it to its initial state.
   160  	GetDatapoint() (value, max, min uint64, isValid bool, average float64, n uint64)
   161  	DatapointValue() (value uint64)
   162  	DatapointMax() (max uint64)
   163  	DatapointMin() (min uint64)
   164  }
   165  
   166  // CountersFactory is an abstract counter factory.
   167  // CountersFactory enables providing of different counter implementations.
   168  type CountersFactory interface {
   169  	// NewCounters returns a counter container.
   170  	// is useCounters is false, the container does not actually do any counting.
   171  	NewCounters(useCounters bool, g0 GoGen) (counters Counters)
   172  }
   173  
   174  const (
   175  	ValueRate        RateType = iota // current rate of increase in value
   176  	ValueMaxRate                     // max seen rate of increase in value
   177  	ValueRateAverage                 // average rate of increase in value during last 10 periods
   178  	RunningRate
   179  	RunningMaxRate
   180  	RunningMaxDecRate
   181  	// accumulated change in running over several intervals
   182  	//	- running value goes up and down
   183  	RunningAverage
   184  	NotAValue // NotAValue is an internal stand-in value indicating a value not in use
   185  )
   186  
   187  type RateType int