Sampling is a way to select a subset of events from total number of events. There are cases where we only want a percenttage or number of messages from total number of messages that we are receiving. There are many ways to accomplish it and simple message counting and only choosing a percent of messge is an acceptable solution in many cases.
type sample struct {
sampleRate float64
sampleEvery int64
numTried atomicInt64
}
func newSampler(rate float64) *sampler {
return &sampler {
sampleRate: rate,
numTried: newInt64(0),
sampleEvery: int64(1.0/sampleRate),
}
}
// sample will return true when a message is sampled
func (s *sampler) sample() bool {
if s.sampleEvery == 0 {
return false
}
return (s.numTried.inc()-1)%t.sampleEvery == 0
}
type atomicInt64 struct {
v int64
}
func newInt64(val int64) atomicInt64 {
return atomicInt64{v: val}
}
func (i *atomicInt64) add(delta int64) int64 {
return atomic.AddInt64(&i.v, delta)
}
func (i *atomicInt64) inc() int64 {
return i.add(1)
}
this sample uses sync/atomic
package from standard library.