Merge pull request #69 from brendandburns/scheduler

Fix the first fit scheduler to randomize.
pull/6/head
Joe Beda 2014-06-11 21:29:51 -07:00
commit 02d9cf2eb9
3 changed files with 23 additions and 10 deletions

View File

@ -21,6 +21,7 @@ import (
"flag"
"fmt"
"log"
"math/rand"
"net/http"
"time"
@ -74,8 +75,9 @@ func main() {
Port: 10250,
}
random := rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
storage := map[string]apiserver.RESTStorage{
"pods": registry.MakePodRegistryStorage(podRegistry, containerInfo, registry.MakeFirstFitScheduler(machineList, podRegistry)),
"pods": registry.MakePodRegistryStorage(podRegistry, containerInfo, registry.MakeFirstFitScheduler(machineList, podRegistry, random)),
"replicationControllers": registry.MakeControllerRegistryStorage(controllerRegistry),
"services": registry.MakeServiceRegistryStorage(serviceRegistry),
}

View File

@ -66,12 +66,14 @@ func (s *RoundRobinScheduler) Schedule(pod Pod) (string, error) {
type FirstFitScheduler struct {
machines []string
registry PodRegistry
random *rand.Rand
}
func MakeFirstFitScheduler(machines []string, registry PodRegistry) Scheduler {
func MakeFirstFitScheduler(machines []string, registry PodRegistry, random *rand.Rand) Scheduler {
return &FirstFitScheduler{
machines: machines,
registry: registry,
random: random,
}
}
@ -96,6 +98,7 @@ func (s *FirstFitScheduler) Schedule(pod Pod) (string, error) {
host := scheduledPod.CurrentState.Host
machineToPods[host] = append(machineToPods[host], scheduledPod)
}
var machineOptions []string
for _, machine := range s.machines {
podFits := true
for _, scheduledPod := range machineToPods[machine] {
@ -108,8 +111,12 @@ func (s *FirstFitScheduler) Schedule(pod Pod) (string, error) {
}
}
if podFits {
return machine, nil
machineOptions = append(machineOptions, machine)
}
}
return "", fmt.Errorf("Failed to find fit for %#v", pod)
if len(machineOptions) == 0 {
return "", fmt.Errorf("Failed to find fit for %#v", pod)
} else {
return machineOptions[s.random.Int()%len(machineOptions)], nil
}
}

View File

@ -47,8 +47,9 @@ func TestRandomScheduler(t *testing.T) {
func TestFirstFitSchedulerNothingScheduled(t *testing.T) {
mockRegistry := MockPodRegistry{}
scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry)
expectSchedule(scheduler, Pod{}, "m1", t)
r := rand.New(rand.NewSource(0))
scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry, r)
expectSchedule(scheduler, Pod{}, "m3", t)
}
func makePod(host string, hostPorts ...int) Pod {
@ -78,8 +79,9 @@ func TestFirstFitSchedulerFirstScheduled(t *testing.T) {
makePod("m1", 8080),
},
}
scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry)
expectSchedule(scheduler, makePod("", 8080), "m2", t)
r := rand.New(rand.NewSource(0))
scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry, r)
expectSchedule(scheduler, makePod("", 8080), "m3", t)
}
func TestFirstFitSchedulerFirstScheduledComplicated(t *testing.T) {
@ -90,7 +92,8 @@ func TestFirstFitSchedulerFirstScheduledComplicated(t *testing.T) {
makePod("m3", 80, 443, 8085),
},
}
scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry)
r := rand.New(rand.NewSource(0))
scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry, r)
expectSchedule(scheduler, makePod("", 8080, 8081), "m3", t)
}
@ -102,7 +105,8 @@ func TestFirstFitSchedulerFirstScheduledImpossible(t *testing.T) {
makePod("m3", 8080),
},
}
scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry)
r := rand.New(rand.NewSource(0))
scheduler := MakeFirstFitScheduler([]string{"m1", "m2", "m3"}, &mockRegistry, r)
_, err := scheduler.Schedule(makePod("", 8080, 8081))
if err == nil {
t.Error("Unexpected non-error.")