You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

64 lines
1.6 KiB

package simulation
import (
"fmt"
)
type LoadBalancerLogic struct{}
func (l LoadBalancerLogic) Tick(props map[string]any, queue []*Request, tick int) ([]*Request, bool) {
// Extract the load balancing algorithm from the props.
algorithm := AsString(props["algorithm"])
// Number of downstream targets
targets := int(AsFloat64(props["_numTargets"]))
if len(queue) == 0 {
return nil, true
}
// Hold the processed requests to be emitted
output := []*Request{}
switch algorithm {
case "least-connection":
// extrat current queue sizes from downstream targets
queueSizesRaw, ok := props["_queueSizes"].(map[string]interface{})
if !ok {
return nil, true
}
// find target with smallest queue
for _, req := range queue {
minTarget := "target-0"
minSize := int(AsFloat64(queueSizesRaw[minTarget]))
for i := 1; i < targets; i++ {
targetKey := fmt.Sprintf("target-%d", i)
size := int(AsFloat64(queueSizesRaw[targetKey]))
if size < minSize {
minTarget = targetKey
minSize = size
}
}
// Clone the request and append the selected target to its path
reqCopy := *req
reqCopy.Path = append(reqCopy.Path, minTarget)
output = append(output, &reqCopy)
}
default:
// Retrieve the last used index
next := int(AsFloat64(props["_rrIndex"]))
for _, req := range queue {
// Clone ther equest and append the selected target to its path
reqCopy := *req
reqCopy.Path = append(reqCopy.Path, fmt.Sprintf("target-%d", next))
output = append(output, &reqCopy)
// Advance to next target
next = (next + 1) % targets
}
props["_rrIndex"] = float64(next)
}
return output, true
}