Skip to content

Instantly share code, notes, and snippets.

@kentquirk
Created November 17, 2022 22:52
Show Gist options
  • Save kentquirk/bc06e36ad10049807a8c2d0d69249c90 to your computer and use it in GitHub Desktop.
Save kentquirk/bc06e36ad10049807a8c2d0d69249c90 to your computer and use it in GitHub Desktop.
Dynamic sampler fun
package main
import (
"fmt"
"math/rand"
"time"
dynsampler "github.com/honeycombio/dynsampler-go"
)
type samplerConfig struct {
Rate uint
WindowSize int
}
type testSampler struct {
sampler dynsampler.Sampler
}
func (t *testSampler) init(config samplerConfig) error {
t.sampler = &dynsampler.AvgSampleWithMin{
GoalSampleRate: int(config.Rate),
ClearFrequencySec: config.WindowSize,
}
if err := t.sampler.Start(); err != nil {
return fmt.Errorf("error starting dynamic sampler: %v", err)
}
return nil
}
func (t *testSampler) send(key string, rate int, done chan struct{}) {
ticker := time.NewTicker(time.Second / time.Duration(rate))
defer ticker.Stop()
for {
select {
case <-ticker.C:
t.sampler.GetSampleRate(key)
case <-done:
return
}
}
}
func main() {
cfg := samplerConfig{
Rate: 50,
WindowSize: 5,
}
t := testSampler{}
t.init(cfg)
done := make(chan struct{})
type testdata struct {
name string
rate int
beginAtTick int
started bool
}
data := []testdata{
{"200", 100000, 0, false},
{"301", 1666, 2, false},
{"403", 1500, 2, false},
{"401", 315, 2, false},
{"400", 35, 2, false},
{"304", 13, 2, false},
{"201", 7, 2, false},
{"429", 7, 2, false},
{"408", 4, 2, false},
{"204", 4, 2, false},
{"413", 2, 2, false},
{"499", 2, 2, false},
{"404", 1, 2, false},
{"302", 1, 2, false},
{"303", 1, 2, false},
{"415", 1, 2, false},
{"206", 1, 2, false},
{"504", 1, 2, false},
{"502", 1, 2, false},
{"STOP", 0, 3600, false},
}
ticker := time.NewTicker(time.Second)
currentTick := 0
var rates map[string]int
outer:
for {
select {
case <-ticker.C:
currentTick++
rates = make(map[string]int)
for i, dt := range data {
if !dt.started {
if currentTick > dt.beginAtTick {
if dt.name == "STOP" {
ticker.Stop()
close(done)
data[i].started = true
fmt.Println("stopping")
break
} else {
fmt.Println("starting " + dt.name)
data[i].started = true
go t.send(dt.name, dt.rate, done)
}
}
} else {
// do all the ones with a rate higher than 1, the others happen less often.
if dt.rate > 1 || rand.Intn(10) == 0 {
rates[dt.name] = t.sampler.GetSampleRate(dt.name)
}
}
}
fmt.Println(rates)
case <-done:
break outer
}
}
fmt.Println(rates)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment