Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 23 additions & 16 deletions pkg/epp/scheduling/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,25 @@ package scheduling

import "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/plugins"

// SchedulerConfig provides a configuration for the scheduler which includes
// items like filters, scorers, etc that influence routing decisions.
//
// This is not threadsafe and the machinery here does not support dynamically
// changing this at runtime, so this should be set once on startup and not
// changed thereafter.
// SchedulerConfig creates a new SchedulerConfig object with the given plugins.
func NewSchedulerConfig(preSchedulePlugins []plugins.PreSchedule, filters []plugins.Filter, scorers map[plugins.Scorer]int,
picker plugins.Picker, postSchedulePlugins []plugins.PostSchedule) *SchedulerConfig {
return &SchedulerConfig{
preSchedulePlugins: preSchedulePlugins,
filters: filters,
scorers: scorers,
picker: picker,
postSchedulePlugins: postSchedulePlugins,
}
}

// SchedulerConfig provides a configuration for the scheduler which influence routing decisions.
type SchedulerConfig struct {
PreSchedulePlugins []plugins.PreSchedule
Filters []plugins.Filter
Scorers map[plugins.Scorer]int // map from scorer to weight
Picker plugins.Picker
PostSchedulePlugins []plugins.PostSchedule
preSchedulePlugins []plugins.PreSchedule
filters []plugins.Filter
scorers map[plugins.Scorer]int // map from scorer to weight
picker plugins.Picker
postSchedulePlugins []plugins.PostSchedule
}

var defPlugin = &defaultPlugin{}
Expand All @@ -39,9 +46,9 @@ var defPlugin = &defaultPlugin{}

// For build time plugins changes, it's recommended to change the defaultConfig variable in this file.
var defaultConfig = &SchedulerConfig{
PreSchedulePlugins: []plugins.PreSchedule{},
Filters: []plugins.Filter{defPlugin},
Scorers: map[plugins.Scorer]int{},
Picker: defPlugin,
PostSchedulePlugins: []plugins.PostSchedule{},
preSchedulePlugins: []plugins.PreSchedule{},
filters: []plugins.Filter{defPlugin},
scorers: map[plugins.Scorer]int{},
picker: defPlugin,
postSchedulePlugins: []plugins.PostSchedule{},
}
10 changes: 5 additions & 5 deletions pkg/epp/scheduling/scheduler.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ func NewScheduler(datastore Datastore) *Scheduler {
func NewSchedulerWithConfig(datastore Datastore, config *SchedulerConfig) *Scheduler {
return &Scheduler{
datastore: datastore,
preSchedulePlugins: config.PreSchedulePlugins,
filters: config.Filters,
scorers: config.Scorers,
picker: config.Picker,
postSchedulePlugins: config.PostSchedulePlugins,
preSchedulePlugins: config.preSchedulePlugins,
filters: config.filters,
scorers: config.scorers,
picker: config.picker,
postSchedulePlugins: config.postSchedulePlugins,
}
}

Expand Down
50 changes: 25 additions & 25 deletions pkg/epp/scheduling/scheduler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,14 +273,14 @@ func TestSchedulePlugins(t *testing.T) {
{
name: "all plugins executed successfully, all scorers with same weight",
config: SchedulerConfig{
PreSchedulePlugins: []plugins.PreSchedule{tp1, tp2},
Filters: []plugins.Filter{tp1, tp2},
Scorers: map[plugins.Scorer]int{
preSchedulePlugins: []plugins.PreSchedule{tp1, tp2},
filters: []plugins.Filter{tp1, tp2},
scorers: map[plugins.Scorer]int{
tp1: 1,
tp2: 1,
},
Picker: pickerPlugin,
PostSchedulePlugins: []plugins.PostSchedule{tp1, tp2},
picker: pickerPlugin,
postSchedulePlugins: []plugins.PostSchedule{tp1, tp2},
},
input: []*backendmetrics.FakePodMetrics{
{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod1"}}},
Expand All @@ -295,14 +295,14 @@ func TestSchedulePlugins(t *testing.T) {
{
name: "all plugins executed successfully, different scorers weights",
config: SchedulerConfig{
PreSchedulePlugins: []plugins.PreSchedule{tp1, tp2},
Filters: []plugins.Filter{tp1, tp2},
Scorers: map[plugins.Scorer]int{
preSchedulePlugins: []plugins.PreSchedule{tp1, tp2},
filters: []plugins.Filter{tp1, tp2},
scorers: map[plugins.Scorer]int{
tp1: 60,
tp2: 40,
},
Picker: pickerPlugin,
PostSchedulePlugins: []plugins.PostSchedule{tp1, tp2},
picker: pickerPlugin,
postSchedulePlugins: []plugins.PostSchedule{tp1, tp2},
},
input: []*backendmetrics.FakePodMetrics{
{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod1"}}},
Expand All @@ -317,14 +317,14 @@ func TestSchedulePlugins(t *testing.T) {
{
name: "filter all",
config: SchedulerConfig{
PreSchedulePlugins: []plugins.PreSchedule{tp1, tp2},
Filters: []plugins.Filter{tp1, tp_filterAll},
Scorers: map[plugins.Scorer]int{
preSchedulePlugins: []plugins.PreSchedule{tp1, tp2},
filters: []plugins.Filter{tp1, tp_filterAll},
scorers: map[plugins.Scorer]int{
tp1: 1,
tp2: 1,
},
Picker: pickerPlugin,
PostSchedulePlugins: []plugins.PostSchedule{tp1, tp2},
picker: pickerPlugin,
postSchedulePlugins: []plugins.PostSchedule{tp1, tp2},
},
input: []*backendmetrics.FakePodMetrics{
{Pod: &backend.Pod{NamespacedName: k8stypes.NamespacedName{Name: "pod1"}}},
Expand All @@ -339,17 +339,17 @@ func TestSchedulePlugins(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
// Reset all plugins before each new test case.
for _, plugin := range test.config.PreSchedulePlugins {
for _, plugin := range test.config.preSchedulePlugins {
plugin.(*TestPlugin).reset()
}
for _, plugin := range test.config.Filters {
for _, plugin := range test.config.filters {
plugin.(*TestPlugin).reset()
}
for plugin := range test.config.Scorers {
for plugin := range test.config.scorers {
plugin.(*TestPlugin).reset()
}
test.config.Picker.(*TestPlugin).reset()
for _, plugin := range test.config.PostSchedulePlugins {
test.config.picker.(*TestPlugin).reset()
for _, plugin := range test.config.postSchedulePlugins {
plugin.(*TestPlugin).reset()
}

Expand Down Expand Up @@ -378,21 +378,21 @@ func TestSchedulePlugins(t *testing.T) {
}

// Validate plugin execution counts dynamically
for _, plugin := range test.config.PreSchedulePlugins {
for _, plugin := range test.config.preSchedulePlugins {
tp, _ := plugin.(*TestPlugin)
if tp.PreScheduleCallCount != 1 {
t.Errorf("Plugin %s PreSchedule() called %d times, expected 1", plugin.Name(), tp.PreScheduleCallCount)
}
}

for _, plugin := range test.config.Filters {
for _, plugin := range test.config.filters {
tp, _ := plugin.(*TestPlugin)
if tp.FilterCallCount != 1 {
t.Errorf("Plugin %s Filter() called %d times, expected 1", plugin.Name(), tp.FilterCallCount)
}
}

for plugin := range test.config.Scorers {
for plugin := range test.config.scorers {
tp, _ := plugin.(*TestPlugin)
if tp.ScoreCallCount != 1 {
t.Errorf("Plugin %s Score() called %d times, expected 1", plugin.Name(), tp.ScoreCallCount)
Expand All @@ -402,7 +402,7 @@ func TestSchedulePlugins(t *testing.T) {
}
}

tp, _ := test.config.Picker.(*TestPlugin)
tp, _ := test.config.picker.(*TestPlugin)
if tp.NumOfPickerCandidates != test.numPodsToScore {
t.Errorf("Picker plugin %s Pick() called with %d candidates, expected %d", tp.Name(), tp.NumOfPickerCandidates, tp.NumOfScoredPods)
}
Expand All @@ -413,7 +413,7 @@ func TestSchedulePlugins(t *testing.T) {
t.Errorf("winnder pod score %v, expected %v", tp.WinnderPodScore, test.targetPodScore)
}

for _, plugin := range test.config.PostSchedulePlugins {
for _, plugin := range test.config.postSchedulePlugins {
tp, _ := plugin.(*TestPlugin)
if tp.PostScheduleCallCount != 1 {
t.Errorf("Plugin %s PostSchedule() called %d times, expected 1", plugin.Name(), tp.PostScheduleCallCount)
Expand Down