Make preemption config a struct to allow for enabling based on scheduler type

This commit is contained in:
Preetha Appan 2018-10-01 09:26:52 -05:00
parent 25a047267f
commit c1c1c230e4
No known key found for this signature in database
GPG Key ID: 9F7C19990A50EAFC
9 changed files with 59 additions and 30 deletions

View File

@ -110,15 +110,20 @@ func (op *Operator) RaftRemovePeerByID(id string, q *WriteOptions) error {
}
type SchedulerConfiguration struct {
// EnablePreemption specifies whether to enable eviction of lower
// PreemptionConfig specifies whether to enable eviction of lower
// priority jobs to place higher priority jobs.
EnablePreemption bool
PreemptionConfig PreemptionConfig
// CreateIndex/ModifyIndex store the create/modify indexes of this configuration.
CreateIndex uint64
ModifyIndex uint64
}
// PreemptionConfig specifies whether preemption is enabled based on scheduler type
type PreemptionConfig struct {
SystemSchedulerEnabled bool
}
// SchedulerGetConfiguration is used to query the current Scheduler configuration.
func (op *Operator) SchedulerGetConfiguration(q *QueryOptions) (*SchedulerConfiguration, *QueryMeta, error) {
var resp SchedulerConfiguration

View File

@ -68,16 +68,16 @@ func TestAPI_OperatorSchedulerGetSetConfiguration(t *testing.T) {
config, _, err = operator.SchedulerGetConfiguration(nil)
r.Check(err)
})
require.False(config.EnablePreemption)
require.True(config.PreemptionConfig.SystemSchedulerEnabled)
// Change a config setting
newConf := &SchedulerConfiguration{EnablePreemption: true}
newConf := &SchedulerConfiguration{PreemptionConfig: PreemptionConfig{SystemSchedulerEnabled: false}}
_, err := operator.SchedulerSetConfiguration(newConf, nil)
require.Nil(err)
config, _, err = operator.SchedulerGetConfiguration(nil)
require.Nil(err)
require.True(config.EnablePreemption)
require.True(config.PreemptionConfig.SystemSchedulerEnabled)
}
func TestAPI_OperatorSchedulerCASConfiguration(t *testing.T) {
@ -93,12 +93,12 @@ func TestAPI_OperatorSchedulerCASConfiguration(t *testing.T) {
config, _, err = operator.SchedulerGetConfiguration(nil)
r.Check(err)
})
require.False(config.EnablePreemption)
require.True(config.PreemptionConfig.SystemSchedulerEnabled)
// Pass an invalid ModifyIndex
{
newConf := &SchedulerConfiguration{
EnablePreemption: true,
PreemptionConfig: PreemptionConfig{SystemSchedulerEnabled: false},
ModifyIndex: config.ModifyIndex - 1,
}
resp, _, err := operator.SchedulerCASConfiguration(newConf, nil)
@ -109,7 +109,7 @@ func TestAPI_OperatorSchedulerCASConfiguration(t *testing.T) {
// Pass a valid ModifyIndex
{
newConf := &SchedulerConfiguration{
EnablePreemption: true,
PreemptionConfig: PreemptionConfig{SystemSchedulerEnabled: false},
ModifyIndex: config.ModifyIndex,
}
resp, _, err := operator.SchedulerCASConfiguration(newConf, nil)

View File

@ -226,7 +226,7 @@ func (s *HTTPServer) OperatorSchedulerConfiguration(resp http.ResponseWriter, re
}
out := api.SchedulerConfiguration{
EnablePreemption: reply.EnablePreemption,
PreemptionConfig: api.PreemptionConfig{SystemSchedulerEnabled: reply.PreemptionConfig.SystemSchedulerEnabled},
CreateIndex: reply.CreateIndex,
ModifyIndex: reply.ModifyIndex,
}
@ -239,11 +239,11 @@ func (s *HTTPServer) OperatorSchedulerConfiguration(resp http.ResponseWriter, re
var conf api.SchedulerConfiguration
if err := decodeBody(req, &conf); err != nil {
return nil, CodedError(http.StatusBadRequest, fmt.Sprintf("Error parsing autopilot config: %v", err))
return nil, CodedError(http.StatusBadRequest, fmt.Sprintf("Error parsing scheduler config: %v", err))
}
args.Config = structs.SchedulerConfiguration{
EnablePreemption: conf.EnablePreemption,
PreemptionConfig: structs.PreemptionConfig{SystemSchedulerEnabled: conf.PreemptionConfig.SystemSchedulerEnabled},
}
// Check for cas value

View File

@ -271,7 +271,7 @@ func TestOperator_SchedulerGetConfiguration(t *testing.T) {
require.Equal(200, resp.Code)
out, ok := obj.(api.SchedulerConfiguration)
require.True(ok)
require.False(out.EnablePreemption)
require.True(out.PreemptionConfig.SystemSchedulerEnabled)
})
}
@ -279,7 +279,9 @@ func TestOperator_SchedulerSetConfiguration(t *testing.T) {
t.Parallel()
httpTest(t, nil, func(s *TestAgent) {
require := require.New(t)
body := bytes.NewBuffer([]byte(`{"EnablePreemption": true}`))
body := bytes.NewBuffer([]byte(`{"PreemptionConfig": {
"SystemSchedulerEnabled": true
}}`))
req, _ := http.NewRequest("PUT", "/v1/operator/scheduler/config", body)
resp := httptest.NewRecorder()
_, err := s.Server.OperatorSchedulerConfiguration(resp, req)
@ -295,7 +297,7 @@ func TestOperator_SchedulerSetConfiguration(t *testing.T) {
var reply structs.SchedulerConfiguration
err = s.RPC("Operator.SchedulerGetConfiguration", &args, &reply)
require.Nil(err)
require.True(reply.EnablePreemption)
require.True(reply.PreemptionConfig.SystemSchedulerEnabled)
})
}
@ -303,7 +305,9 @@ func TestOperator_SchedulerCASConfiguration(t *testing.T) {
t.Parallel()
httpTest(t, nil, func(s *TestAgent) {
require := require.New(t)
body := bytes.NewBuffer([]byte(`{"EnablePreemption": true}`))
body := bytes.NewBuffer([]byte(`{"PreemptionConfig": {
"SystemSchedulerEnabled": true
}}`))
req, _ := http.NewRequest("PUT", "/v1/operator/scheduler/config", body)
resp := httptest.NewRecorder()
_, err := s.Server.OperatorSchedulerConfiguration(resp, req)
@ -320,11 +324,13 @@ func TestOperator_SchedulerCASConfiguration(t *testing.T) {
if err := s.RPC("Operator.SchedulerGetConfiguration", &args, &reply); err != nil {
t.Fatalf("err: %v", err)
}
require.True(reply.EnablePreemption)
require.True(reply.PreemptionConfig.SystemSchedulerEnabled)
// Create a CAS request, bad index
{
buf := bytes.NewBuffer([]byte(`{"EnablePreemption": true}`))
buf := bytes.NewBuffer([]byte(`{"PreemptionConfig": {
"SystemSchedulerEnabled": false
}}`))
req, _ := http.NewRequest("PUT", fmt.Sprintf("/v1/operator/scheduler/config?cas=%d", reply.ModifyIndex-1), buf)
resp := httptest.NewRecorder()
obj, err := s.Server.OperatorSchedulerConfiguration(resp, req)
@ -334,7 +340,9 @@ func TestOperator_SchedulerCASConfiguration(t *testing.T) {
// Create a CAS request, good index
{
buf := bytes.NewBuffer([]byte(`{"EnablePreemption": true}`))
buf := bytes.NewBuffer([]byte(`{"PreemptionConfig": {
"SystemSchedulerEnabled": false
}}`))
req, _ := http.NewRequest("PUT", fmt.Sprintf("/v1/operator/scheduler/config?cas=%d", reply.ModifyIndex), buf)
resp := httptest.NewRecorder()
obj, err := s.Server.OperatorSchedulerConfiguration(resp, req)
@ -346,6 +354,6 @@ func TestOperator_SchedulerCASConfiguration(t *testing.T) {
if err := s.RPC("Operator.SchedulerGetConfiguration", &args, &reply); err != nil {
t.Fatalf("err: %v", err)
}
require.True(reply.EnablePreemption)
require.False(reply.PreemptionConfig.SystemSchedulerEnabled)
})
}

View File

@ -2835,7 +2835,9 @@ func TestFSM_SchedulerConfig(t *testing.T) {
// Set the autopilot config using a request.
req := structs.SchedulerSetConfigRequest{
Config: structs.SchedulerConfiguration{
EnablePreemption: true,
PreemptionConfig: structs.PreemptionConfig{
SystemSchedulerEnabled: true,
},
},
}
buf, err := structs.Encode(structs.SchedulerConfigRequestType, req)
@ -2850,11 +2852,11 @@ func TestFSM_SchedulerConfig(t *testing.T) {
_, config, err := fsm.state.SchedulerConfig()
require.Nil(err)
require.Equal(config.EnablePreemption, req.Config.EnablePreemption)
require.Equal(config.PreemptionConfig.SystemSchedulerEnabled, req.Config.PreemptionConfig.SystemSchedulerEnabled)
// Now use CAS and provide an old index
req.CAS = true
req.Config.EnablePreemption = false
req.Config.PreemptionConfig = structs.PreemptionConfig{SystemSchedulerEnabled: false}
req.Config.ModifyIndex = config.ModifyIndex - 1
buf, err = structs.Encode(structs.SchedulerConfigRequestType, req)
require.Nil(err)
@ -2867,5 +2869,5 @@ func TestFSM_SchedulerConfig(t *testing.T) {
_, config, err = fsm.state.SchedulerConfig()
require.Nil(err)
// Verify that preemption is still enabled
require.True(config.EnablePreemption)
require.True(config.PreemptionConfig.SystemSchedulerEnabled)
}

View File

@ -1246,7 +1246,7 @@ func (s *Server) getOrCreateSchedulerConfig() *structs.SchedulerConfiguration {
return config
}
config = &structs.SchedulerConfiguration{EnablePreemption: false}
config = &structs.SchedulerConfiguration{PreemptionConfig: structs.PreemptionConfig{SystemSchedulerEnabled: true}}
req := structs.SchedulerSetConfigRequest{Config: *config}
if _, _, err = s.raftApply(structs.SchedulerConfigRequestType, req); err != nil {
s.logger.Named("core").Error("failed to initialize config", "error", err)

View File

@ -121,15 +121,21 @@ type AutopilotConfig struct {
}
type SchedulerConfiguration struct {
// EnablePreemption specifies whether to enable eviction of lower
// PreemptionConfig specifies whether to enable eviction of lower
// priority jobs to place higher priority jobs.
EnablePreemption bool
PreemptionConfig PreemptionConfig
// CreateIndex/ModifyIndex store the create/modify indexes of this configuration.
CreateIndex uint64
ModifyIndex uint64
}
// PreemptionConfig specifies whether preemption is enabled based on scheduler type
type PreemptionConfig struct {
// SystemSchedulerEnabled specifies if preemption is enabled for system jobs
SystemSchedulerEnabled bool
}
// SchedulerSetConfigRequest is used by the Operator endpoint to update the
// current Scheduler configuration of the cluster.
type SchedulerSetConfigRequest struct {

View File

@ -287,9 +287,9 @@ func NewSystemStack(ctx Context) *SystemStack {
// by a particular task group. Enable eviction as system jobs are high
// priority.
_, schedConfig, _ := s.ctx.State().SchedulerConfig()
enablePreemption := false
enablePreemption := true
if schedConfig != nil {
enablePreemption = schedConfig.EnablePreemption
enablePreemption = schedConfig.PreemptionConfig.SystemSchedulerEnabled
}
s.binPack = NewBinPackIterator(ctx, rankSource, enablePreemption, 0)

View File

@ -243,7 +243,11 @@ func TestSystemSched_ExhaustResources(t *testing.T) {
noErr(t, h.State.UpsertNode(h.NextIndex(), node))
// Enable Preemption
h.State.SchedulerSetConfig(h.NextIndex(), &structs.SchedulerConfiguration{EnablePreemption: true})
h.State.SchedulerSetConfig(h.NextIndex(), &structs.SchedulerConfiguration{
PreemptionConfig: structs.PreemptionConfig{
SystemSchedulerEnabled: true,
},
})
// Create a service job which consumes most of the system resources
svcJob := mock.Job()
@ -1577,7 +1581,11 @@ func TestSystemSched_Preemption(t *testing.T) {
}
// Enable Preemption
h.State.SchedulerSetConfig(h.NextIndex(), &structs.SchedulerConfiguration{EnablePreemption: true})
h.State.SchedulerSetConfig(h.NextIndex(), &structs.SchedulerConfiguration{
PreemptionConfig: structs.PreemptionConfig{
SystemSchedulerEnabled: true,
},
})
// Create some low priority batch jobs and allocations for them
// One job uses a reserved port