← Back Home

Write a counting Message Sampler in Go

  1. go
  2. sampling

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.