Skip to content
Snippets Groups Projects
Commit ee4847fd authored by ale's avatar ale
Browse files

minor cleanups to lb spec syntax

parent 7e02e304
No related branches found
No related tags found
No related merge requests found
......@@ -18,7 +18,7 @@ var (
httpPort = flag.Int("http-port", 80, "HTTP port")
staticDir = flag.String("static-dir", "/usr/share/autoradio/htdocs/static", "Static content directory")
templateDir = flag.String("template-dir", "/usr/share/autoradio/htdocs/templates", "HTML templates directory")
lbPolicy = flag.String("lb-policy", "weighted", "Load balancing policy (weighted, leastloaded)")
lbPolicy = flag.String("lb-policy", "listeners_available,listeners_score,weighted", "Load balancing rules specification (see godoc documentation for details)")
// Default DNS TTL (seconds).
dnsTtl = 5
......
package fe
import (
"errors"
"fmt"
"net"
"strings"
......@@ -108,32 +109,45 @@ func (l *autoradioLoadBalancer) Choose(ctx lbv2.RequestContext) *autoradio.NodeS
return result.(*lbNode).NodeStatus
}
// Parse a string that specifies how to build a LoadBalancer. The
// string should consist of a list of comma-separated tokens, each
// identifying a specific filter or policy.
//
// Some filters will always be included in the resulting LoadBalancer
// and do not need to be specified explicitly (icecastActiveFilter and
// ipProtocolFilter, plus an activeNodesFilter at the end).
func parseLoadBalancerSpec(specstr string) (*autoradioLoadBalancer, error) {
lb := lbv2.New()
lb.AddFilter(newIcecastActiveFilter())
lb.AddFilter(newIpProtocolFilter())
var policy lbv2.Policy
for _, spec := range strings.Split(specstr, ",") {
switch spec {
case "ba", "bw_avail", "bandwidth_available":
case "bandwidth_available":
lb.AddFilter(lbv2.NewCapacityAvailableFilter(lb.GetPredictor(UTIL_BANDWIDTH)))
case "la", "listeners_available":
case "listeners_available":
lb.AddFilter(lbv2.NewCapacityAvailableFilter(lb.GetPredictor(UTIL_LISTENERS)))
case "bw", "bandwidth_weight":
case "bandwidth_score":
lb.AddFilter(lbv2.NewCapacityAvailableScorer(lb.GetPredictor(UTIL_BANDWIDTH)))
case "lw", "listeners_weight":
case "listeners_score":
lb.AddFilter(lbv2.NewCapacityAvailableScorer(lb.GetPredictor(UTIL_LISTENERS)))
case "random":
lb.SetPolicy(lbv2.RandomPolicy)
policy = lbv2.RandomPolicy
case "weighted":
lb.SetPolicy(lbv2.WeightedPolicy)
policy = lbv2.WeightedPolicy
case "best":
lb.SetPolicy(lbv2.HighestScorePolicy)
policy = lbv2.HighestScorePolicy
default:
return nil, fmt.Errorf("unknown lb filter spec \"%s\"", spec)
}
}
if policy == nil {
return nil, errors.New("no lb policy specified")
}
lb.SetPolicy(policy)
lb.AddFilter(lbv2.NewActiveNodesFilter())
return &autoradioLoadBalancer{lb}, nil
......
......@@ -104,13 +104,13 @@ func TestLoadBalancer_Policies(t *testing.T) {
}
// Weighted should return node1 4 times as often as node2.
runLBTest(t, nodes, nil, "bw,weighted", 1000, map[string]int{"node1": 200, "node2": 800})
runLBTest(t, nodes, nil, "bandwidth_score,weighted", 1000, map[string]int{"node1": 200, "node2": 800})
// The 'random' policy will ignore the weights.
runLBTest(t, nodes, nil, "bw,random", 1000, map[string]int{"node1": 500, "node2": 500})
runLBTest(t, nodes, nil, "bandwidth_score,random", 1000, map[string]int{"node1": 500, "node2": 500})
// The 'best' policy will always return node2.
runLBTest(t, nodes, nil, "bw,best", 1000, map[string]int{"node2": 1000})
runLBTest(t, nodes, nil, "bandwidth_score,best", 1000, map[string]int{"node2": 1000})
}
func TestLoadBalancer_PoliciesIgnoreDisabledNodes(t *testing.T) {
......@@ -127,7 +127,7 @@ func TestLoadBalancer_PoliciesIgnoreDisabledNodes(t *testing.T) {
},
}
for _, spec := range []string{"bw_avail,weighted", "bw_avail,random", "bw_avail,best"} {
for _, spec := range []string{"bandwidth_available,weighted", "bandwidth_available,random", "bandwidth_available,best"} {
runLBTest(t, nodes, nil, spec, 1000, map[string]int{"node1": 1000})
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment