Skip to content

Instantly share code, notes, and snippets.

@avrebarra
Last active April 18, 2022 05:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save avrebarra/0db7f69db2ba8dd3a0eb6fe369471196 to your computer and use it in GitHub Desktop.
Save avrebarra/0db7f69db2ba8dd3a0eb6fe369471196 to your computer and use it in GitHub Desktop.
Golang Weighted Response Engine
package main
import (
"fmt"
"math/rand"
"github.com/go-playground/validator"
)
type RespSpec struct {
Value interface{}
Weight float64
}
type RespEngine struct {
Config RespEngineConfig
}
type RespEngineConfig struct {
SpecMap map[string][]RespSpec `validate:"required"`
}
func NewRespEngine(cfg RespEngineConfig) (*RespEngine, error) {
if err := validator.New().Struct(cfg); err != nil {
return nil, err
}
return &RespEngine{Config: cfg}, nil
}
func (e *RespEngine) FetchResp(procname string) (resp interface{}) {
// check existence
spec, exist := e.Config.SpecMap[procname]
if !exist {
return nil
}
// count value
totProbability := 0
for _, v := range spec {
totProbability += int(v.Weight)
}
// iterate correct value
chosenbar := rand.Float64() * float64(totProbability)
for _, v := range spec {
chosenbar -= v.Weight
if chosenbar <= 0 {
return v.Value
}
}
return
}
// ***
var ng *RespEngine
func init() {
var err error
ng, err = NewRespEngine(RespEngineConfig{
SpecMap: map[string][]RespSpec{
"transaction.error": {
RespSpec{Weight: 1, Value: fmt.Errorf("damn error happened")},
RespSpec{Weight: 5, Value: fmt.Errorf("damn bigger error probability happened")},
},
},
})
if err != nil {
err = fmt.Errorf("cannot start resp engine: %w", err)
panic(err)
}
}
// ***
func main() {
for i := 0; i < 100; i++ {
fmt.Println(ng.FetchResp("transaction.error"))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment