diff --git a/pkg/scheduler/cache/candidate/base.go b/pkg/scheduler/cache/candidate/base.go index 5619f87b4f..c123272524 100644 --- a/pkg/scheduler/cache/candidate/base.go +++ b/pkg/scheduler/cache/candidate/base.go @@ -33,8 +33,6 @@ import ( schedmodels "yunion.io/x/onecloud/pkg/scheduler/models" ) -var ErrInstanceGroupNotFound = errors.Error("InstanceGroupNotFound") - type BaseHostDesc struct { *computemodels.SHost Region *computemodels.SCloudregion `json:"region"` @@ -138,7 +136,7 @@ func (b baseHostGetter) GetFreeGroupCount(groupId string) (int, error) { // Must Be scg, ok := b.h.InstanceGroups[groupId] if !ok { - return 0, errors.Wrap(ErrInstanceGroupNotFound, groupId) + return 0, errors.Wrap(core.ErrInstanceGroupNotFound, groupId) } free := scg.Granularity - scg.ReferCount if free < 1 { diff --git a/pkg/scheduler/core/generic_scheduler.go b/pkg/scheduler/core/generic_scheduler.go index db72c0a9b1..e3d90498d9 100644 --- a/pkg/scheduler/core/generic_scheduler.go +++ b/pkg/scheduler/core/generic_scheduler.go @@ -15,7 +15,6 @@ package core import ( - "encoding/json" "fmt" "sort" "strings" @@ -29,9 +28,6 @@ import ( utiltrace "yunion.io/x/pkg/util/trace" "yunion.io/x/pkg/util/workqueue" - "yunion.io/x/onecloud/pkg/apis/compute" - schedapi "yunion.io/x/onecloud/pkg/apis/scheduler" - "yunion.io/x/onecloud/pkg/scheduler/api" o "yunion.io/x/onecloud/pkg/scheduler/options" ) @@ -104,7 +100,7 @@ func NewGenericScheduler(s Scheduler) (*GenericScheduler, error) { return g, nil } -func (g *GenericScheduler) Schedule(unit *Unit, candidates []Candidater) (*SchedResultItemList, error) { +func (g *GenericScheduler) Schedule(unit *Unit, candidates []Candidater, helper IResultHelper) (*ScheduleResult, error) { startTime := time.Now() defer func() { log.V(4).Infof("Schedule cost time: %v", time.Since(startTime)) @@ -171,7 +167,8 @@ func (g *GenericScheduler) Schedule(unit *Unit, candidates []Candidater) (*Sched return nil, err } - return &SchedResultItemList{Unit: unit, Data: resultItems}, nil + itemList := &SchedResultItemList{Unit: unit, Data: resultItems} + return helper.ResultHelp(itemList, unit.SchedInfo), nil } func newSchedResultByCtx(u *Unit, count int64, c Candidater) *SchedResultItem { @@ -238,24 +235,6 @@ func generateScheduleResult(u *Unit, scs []*SelectedCandidate, cs []Candidater) return results, nil } -type SchedResultItem struct { - ID string `json:"id"` - Name string `json:"name"` - Count int64 `json:"count"` - Data map[string]interface{} `json:"data"` - Capacity int64 `json:"capacity"` - Score Score `json:"score"` - - CapacityDetails map[string]int64 `json:"capacity_details"` - ScoreDetails string `json:"score_details"` - - Candidater Candidater `json:"-"` - - *AllocatedResource - - SchedData *api.SchedInfo -} - type StorageUsed struct { used map[string]int64 } @@ -285,27 +264,6 @@ func (s *StorageUsed) Add(storageId string, used int64) { } } -func (item *SchedResultItem) ToCandidateResource(storageUsed *StorageUsed) *schedapi.CandidateResource { - return &schedapi.CandidateResource{ - HostId: item.ID, - Name: item.Name, - Disks: item.getDisks(storageUsed), - Nets: item.Nets, - } -} - -func (item *SchedResultItem) getDisks(used *StorageUsed) []*schedapi.CandidateDisk { - inputs := item.SchedData.Disks - ret := make([]*schedapi.CandidateDisk, 0) - for idx, disk := range item.Disks { - ret = append(ret, &schedapi.CandidateDisk{ - Index: idx, - StorageIds: item.getSortStorageIds(used, inputs[idx], disk.Storages), - }) - } - return ret -} - type sortStorage struct { Id string FeeSize int64 @@ -335,31 +293,6 @@ func (s sortStorages) getIds() []string { return ret } -func (item *SchedResultItem) getSortStorageIds( - used *StorageUsed, - disk *compute.DiskConfig, - storages []*schedapi.CandidateStorage) []string { - reqSize := disk.SizeMb - ss := make([]sortStorage, 0) - for _, s := range storages { - ss = append(ss, sortStorage{ - Id: s.Id, - FeeSize: s.FreeCapacity - used.Get(s.Id), - }) - } - toSort := sortStorages(ss) - sort.Sort(toSort) - sortedStorages := toSort.getIds() - ret := make([]string, 0) - for idx, id := range sortedStorages { - if idx == 0 { - used.Add(id, int64(reqSize)) - } - ret = append(ret, id) - } - return ret -} - func GetCapacities(u *Unit, id string) (res map[string]int64) { res = make(map[string]int64) capacities := u.GetCapacities(id) @@ -371,51 +304,6 @@ func GetCapacities(u *Unit, id string) (res map[string]int64) { return } -type SchedResultItems []*SchedResultItem - -func (its SchedResultItems) Len() int { - return len(its) -} - -func (its SchedResultItems) Swap(i, j int) { - its[i], its[j] = its[j], its[i] -} - -func (its SchedResultItems) Less(i, j int) bool { - it1, it2 := its[i], its[j] - return it1.Capacity < it2.Capacity - /* - ctx := its.Unit - - m := func(c int64) int64 { - if c > 0 { - return 1 - } - return 0 - } - - v := func(count, capacity, score int64) int64 { - return (m(count) << 42) | (m(capacity) << 21) | score - } - - count1, count2 := it1.Count, it2.Count - capacity1, capacity2 := ctx.GetCapacity(it1.ID), ctx.GetCapacity(it2.ID) - score1, score2 := int64(ctx.GetScore(it1.ID)), int64(ctx.GetScore(it2.ID)) - - return v(count1, capacity1, score1) < v(count2, capacity2, score2) - */ -} - -type SchedResultItemList struct { - Unit *Unit - Data SchedResultItems -} - -func (its SchedResultItemList) String() string { - bytes, _ := json.Marshal(its.Data) - return string(bytes) -} - type SelectedCandidate struct { Count int64 Candidate Candidater @@ -536,7 +424,11 @@ func findCandidatesThatFit(unit *Unit, candidates []Candidater, predicates map[s unit.AppendFailedCandidates(fcs) } } - workqueue.Parallelize(o.GetOptions().PredicateParallelizeSize, len(candidates), checkUnit) + workerSize := o.GetOptions().PredicateParallelizeSize + if workerSize == 0 { + workerSize = 1 + } + workqueue.Parallelize(workerSize, len(candidates), checkUnit) filtered = filtered[:filteredLen] if len(errsChannel) > 0 { errs := make([]error, 0) diff --git a/pkg/scheduler/manager/instancegroup_select.go b/pkg/scheduler/core/instancegroup_select.go similarity index 94% rename from pkg/scheduler/manager/instancegroup_select.go rename to pkg/scheduler/core/instancegroup_select.go index 969d71db24..242c272c02 100644 --- a/pkg/scheduler/manager/instancegroup_select.go +++ b/pkg/scheduler/core/instancegroup_select.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package manager +package core import ( "fmt" @@ -26,12 +26,10 @@ import ( schedapi "yunion.io/x/onecloud/pkg/apis/scheduler" "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/scheduler/api" - "yunion.io/x/onecloud/pkg/scheduler/cache/candidate" - "yunion.io/x/onecloud/pkg/scheduler/core" "yunion.io/x/onecloud/pkg/scheduler/core/score" ) -func transToInstanceGroupSchedResult(result *core.SchedResultItemList, schedInfo *api.SchedInfo) *schedapi.ScheduleOutput { +func transToInstanceGroupSchedResult(result *SchedResultItemList, schedInfo *api.SchedInfo) *schedapi.ScheduleOutput { for _, item := range result.Data { item.Count = 0 } @@ -50,7 +48,7 @@ type sGuestInfo struct { } type sSchedResultItem struct { - *core.SchedResultItem + *SchedResultItem instanceGroupCapacity map[string]int64 masterCount int64 backupCount int64 @@ -69,7 +67,7 @@ func (item *sSchedResultItem) minInstanceGroupCapacity(groupSet map[string]*mode return mincapa } -func buildHosts(result *core.SchedResultItemList, groups map[string]*models.SGroup) []*sSchedResultItem { +func buildHosts(result *SchedResultItemList, groups map[string]*models.SGroup) []*sSchedResultItem { hosts := make([]*sSchedResultItem, result.Data.Len()) for i := 0; i < len(result.Data); i++ { getter := result.Data[i].Candidater.Getter() @@ -77,7 +75,7 @@ func buildHosts(result *core.SchedResultItemList, groups map[string]*models.SGro for id, group := range groups { c, err := getter.GetFreeGroupCount(id) if err != nil { - if errors.Cause(err) == candidate.ErrInstanceGroupNotFound { + if errors.Cause(err) == ErrInstanceGroupNotFound { igCapacity[id] = int64(group.Granularity) } else { igCapacity[id] = 0 @@ -124,7 +122,7 @@ func sortHosts(hosts []*sSchedResultItem, guestInfo *sGuestInfo, isBackup *bool) // scoreNormalization compare the value of s1 and s2. // If s1 is less than s2, return 1, 0 which means s2 is better than s1. -func scoreNormalization(s1, s2 core.Score) (int64, int64) { +func scoreNormalization(s1, s2 Score) (int64, int64) { sb1, sb2 := s1.ScoreBucket, s2.ScoreBucket preferLess := score.PreferLess(sb1, sb2) avoidLess := score.AvoidLess(sb1, sb2) @@ -213,7 +211,8 @@ func hostsIndex(hostId string, hosts []*sSchedResultItem) int { // getBackupSchedResult return the ScheduleOutput for guest without backup func getSchedResult(hosts []*sSchedResultItem, guestInfos []sGuestInfo, sid string) *schedapi.ScheduleOutput { apiResults := make([]*schedapi.CandidateResource, 0) - storageUsed := core.NewStorageUsed() + storageUsed := + NewStorageUsed() var i int = 0 for ; i < len(guestInfos); i++ { host := selectHost(hosts, guestInfos[i], nil, true) @@ -244,7 +243,7 @@ func getBackupSchedResult(hosts []*sSchedResultItem, guestInfos, backGuestInfos wireHostMap := buildWireHosts(hosts) apiResults := make([]*schedapi.CandidateResource, 0, len(guestInfos)) nowireIds := sets.NewString() - storageUsed := core.NewStorageUsed() + storageUsed := NewStorageUsed() isBackup := true isMaster := false for i := 0; i < len(guestInfos); i++ { diff --git a/pkg/scheduler/core/result.go b/pkg/scheduler/core/result.go new file mode 100644 index 0000000000..1dea07d2af --- /dev/null +++ b/pkg/scheduler/core/result.go @@ -0,0 +1,122 @@ +// Copyright 2019 Yunion +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package core + +import ( + "encoding/json" + "sort" + + "yunion.io/x/onecloud/pkg/apis/compute" + schedapi "yunion.io/x/onecloud/pkg/apis/scheduler" + "yunion.io/x/onecloud/pkg/scheduler/api" +) + +type ScheduleResult struct { + // Result is sync schedule result + Result *schedapi.ScheduleOutput + // ForecastResult is forecast schedule result + ForecastResult interface{} + // TestResult is test schedule result + TestResult interface{} +} + +type SchedResultItem struct { + ID string `json:"id"` + Name string `json:"name"` + Count int64 `json:"count"` + Data map[string]interface{} `json:"data"` + Capacity int64 `json:"capacity"` + Score Score `json:"score"` + + CapacityDetails map[string]int64 `json:"capacity_details"` + ScoreDetails string `json:"score_details"` + + Candidater Candidater `json:"-"` + + *AllocatedResource + + SchedData *api.SchedInfo +} + +type SchedResultItemList struct { + Unit *Unit + Data SchedResultItems +} + +func (its SchedResultItemList) String() string { + bytes, _ := json.Marshal(its.Data) + return string(bytes) +} + +type SchedResultItems []*SchedResultItem + +func (its SchedResultItems) Len() int { + return len(its) +} + +func (its SchedResultItems) Swap(i, j int) { + its[i], its[j] = its[j], its[i] +} + +func (its SchedResultItems) Less(i, j int) bool { + it1, it2 := its[i], its[j] + return it1.Capacity < it2.Capacity +} + +func (item *SchedResultItem) ToCandidateResource(storageUsed *StorageUsed) *schedapi.CandidateResource { + return &schedapi.CandidateResource{ + HostId: item.ID, + Name: item.Name, + Disks: item.getDisks(storageUsed), + Nets: item.Nets, + } +} + +func (item *SchedResultItem) getDisks(used *StorageUsed) []*schedapi.CandidateDisk { + inputs := item.SchedData.Disks + ret := make([]*schedapi.CandidateDisk, 0) + for idx, disk := range item.Disks { + ret = append(ret, &schedapi.CandidateDisk{ + Index: idx, + StorageIds: item.getSortStorageIds(used, inputs[idx], disk.Storages), + }) + } + return ret +} + +func (item *SchedResultItem) getSortStorageIds( + used *StorageUsed, + disk *compute.DiskConfig, + storages []*schedapi.CandidateStorage) []string { + reqSize := disk.SizeMb + ss := make([]sortStorage, 0) + for _, s := range storages { + ss = append(ss, sortStorage{ + Id: s.Id, + FeeSize: s.FreeCapacity - used.Get(s.Id), + }) + } + toSort := sortStorages(ss) + sort.Sort(toSort) + sortedStorages := toSort.getIds() + ret := make([]string, 0) + for idx, id := range sortedStorages { + if idx == 0 { + used.Add(id, int64(reqSize)) + } + ret = append(ret, id) + } + return ret +} diff --git a/pkg/scheduler/manager/result_helper.go b/pkg/scheduler/core/result_helper.go similarity index 67% rename from pkg/scheduler/manager/result_helper.go rename to pkg/scheduler/core/result_helper.go index 8ded1924ff..3ce1f155c4 100644 --- a/pkg/scheduler/manager/result_helper.go +++ b/pkg/scheduler/core/result_helper.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package manager +package core import ( "fmt" @@ -20,13 +20,40 @@ import ( "yunion.io/x/log" schedapi "yunion.io/x/onecloud/pkg/apis/scheduler" - computemodels "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/scheduler/api" - "yunion.io/x/onecloud/pkg/scheduler/core" - schedmodels "yunion.io/x/onecloud/pkg/scheduler/models" ) -func transToSchedResult(result *core.SchedResultItemList, schedInfo *api.SchedInfo) *schedapi.ScheduleOutput { +func ResultHelp(result *SchedResultItemList, schedInfo *api.SchedInfo) *ScheduleResult { + out := new(ScheduleResult) + out.Result = transToSchedResult(result, schedInfo) + return out +} + +func ResultHelpForForcast(result *SchedResultItemList, _ *api.SchedInfo) *ScheduleResult { + out := new(ScheduleResult) + out.ForecastResult = transToSchedForecastResult(result) + return out +} + +func ResultHelpForTest(result *SchedResultItemList, schedInfo *api.SchedInfo) *ScheduleResult { + out := new(ScheduleResult) + out.TestResult = transToSchedTestResult(result, schedInfo.SuggestionLimit) + return out +} + +type IResultHelper interface { + ResultHelp(result *SchedResultItemList, schedInfo *api.SchedInfo) *ScheduleResult +} + +// ResultHelperFunc type is an adapter to allwo the use of ordinary functions as a ResultHelper. +// If f is a function with the appropriate signature, ResultHelperFunc(f) is a ResultHelper that calls f. +type SResultHelperFunc func(result *SchedResultItemList, schedInfo *api.SchedInfo) *ScheduleResult + +func (r SResultHelperFunc) ResultHelp(result *SchedResultItemList, schedInfo *api.SchedInfo) *ScheduleResult { + return r(result, schedInfo) +} + +func transToSchedResult(result *SchedResultItemList, schedInfo *api.SchedInfo) *schedapi.ScheduleOutput { if schedInfo.Backup || len(schedInfo.InstanceGroupsDetail) > 0 { return transToInstanceGroupSchedResult(result, schedInfo) } else { @@ -34,24 +61,10 @@ func transToSchedResult(result *core.SchedResultItemList, schedInfo *api.SchedIn } } -func setSchedPendingUsage(driver computemodels.IGuestDriver, req *api.SchedInfo, resp *schedapi.ScheduleOutput) error { - if req.IsSuggestion || IsDriverSkipScheduleDirtyMark(driver) || req.SkipDirtyMarkHost() { - return nil - } - for _, item := range resp.Candidates { - schedmodels.HostPendingUsageManager.AddPendingUsage(req, item) - } - return nil -} - -func IsDriverSkipScheduleDirtyMark(driver computemodels.IGuestDriver) bool { - return !(driver.DoScheduleCPUFilter() && driver.DoScheduleMemoryFilter() && driver.DoScheduleStorageFilter()) -} - -func transToRegionSchedResult(result core.SchedResultItems, count int64, sid string) *schedapi.ScheduleOutput { +func transToRegionSchedResult(result SchedResultItems, count int64, sid string) *schedapi.ScheduleOutput { apiResults := make([]*schedapi.CandidateResource, 0) succCount := 0 - storageUsed := core.NewStorageUsed() + storageUsed := NewStorageUsed() for _, nr := range result { for { if nr.Count <= 0 { @@ -79,7 +92,7 @@ func transToRegionSchedResult(result core.SchedResultItems, count int64, sid str } } -func hostInResultItemsIndex(hostId string, hosts core.SchedResultItems) int { +func hostInResultItemsIndex(hostId string, hosts SchedResultItems) int { for i := 0; i < len(hosts); i++ { if hosts[i].ID == hostId { return i @@ -88,7 +101,7 @@ func hostInResultItemsIndex(hostId string, hosts core.SchedResultItems) int { return -1 } -func transToSchedTestResult(result *core.SchedResultItemList, limit int64) interface{} { +func transToSchedTestResult(result *SchedResultItemList, limit int64) interface{} { return &api.SchedTestResult{ Data: result.Data, Total: int64(result.Data.Len()), @@ -97,7 +110,7 @@ func transToSchedTestResult(result *core.SchedResultItemList, limit int64) inter } } -func transToSchedForecastResult(result *core.SchedResultItemList) interface{} { +func transToSchedForecastResult(result *SchedResultItemList) interface{} { unit := result.Unit schedData := unit.SchedData() reqCount := int64(schedData.Count) @@ -118,13 +131,13 @@ func transToSchedForecastResult(result *core.SchedResultItemList) interface{} { } } - logIndex := func(item *core.SchedResultItem) string { + logIndex := func(item *SchedResultItem) string { getter := item.Candidater.Getter() name := getter.Name() id := getter.Id() return fmt.Sprintf("%s:%s", name, id) } - addInfos := func(logs core.SchedLogList, item *core.SchedResultItem) { + addInfos := func(logs SchedLogList, item *SchedResultItem) { for preName, cnt := range item.CapacityDetails { if cnt > 0 { continue @@ -145,7 +158,7 @@ func transToSchedForecastResult(result *core.SchedResultItemList) interface{} { } } - items := make(core.SchedResultItems, 0) + items := make(SchedResultItems, 0) for _, item := range result.Data { hostType := item.Candidater.Getter().HostType() if schedData.Hypervisor == hostType { diff --git a/pkg/scheduler/core/types.go b/pkg/scheduler/core/types.go index 841e081cc1..3258fc5914 100644 --- a/pkg/scheduler/core/types.go +++ b/pkg/scheduler/core/types.go @@ -18,6 +18,7 @@ import ( "strings" "yunion.io/x/jsonutils" + "yunion.io/x/pkg/errors" computeapi "yunion.io/x/onecloud/pkg/apis/compute" schedapi "yunion.io/x/onecloud/pkg/apis/scheduler" @@ -34,6 +35,8 @@ const ( PriorityStep int = 1 ) +var ErrInstanceGroupNotFound = errors.Error("InstanceGroupNotFound") + type FailedCandidate struct { Stage string Candidate Candidater diff --git a/pkg/scheduler/manager/manager.go b/pkg/scheduler/manager/manager.go index 80469a9c78..370c3360ad 100644 --- a/pkg/scheduler/manager/manager.go +++ b/pkg/scheduler/manager/manager.go @@ -96,7 +96,7 @@ func (sm *SchedulerManager) start() { } } -func (sm *SchedulerManager) schedule(info *api.SchedInfo) (*ScheduleResult, error) { +func (sm *SchedulerManager) schedule(info *api.SchedInfo) (*core.ScheduleResult, error) { log.V(10).Infof("SchedulerManager do schedule, input: %#v", info) task, err := sm.TaskManager.AddTask(sm, info) if err != nil { @@ -121,7 +121,7 @@ func NewSessionID() string { // Schedule process the request data that is scheduled for dispatch and complements // the session information. -func Schedule(info *api.SchedInfo) (*ScheduleResult, error) { +func Schedule(info *api.SchedInfo) (*core.ScheduleResult, error) { if len(info.SessionId) == 0 { info.SessionId = NewSessionID() } diff --git a/pkg/scheduler/manager/task_queue.go b/pkg/scheduler/manager/task_queue.go index 2f9dc9b502..57072d93e4 100644 --- a/pkg/scheduler/manager/task_queue.go +++ b/pkg/scheduler/manager/task_queue.go @@ -24,8 +24,10 @@ import ( "yunion.io/x/pkg/errors" schedapi "yunion.io/x/onecloud/pkg/apis/scheduler" + computemodels "yunion.io/x/onecloud/pkg/compute/models" "yunion.io/x/onecloud/pkg/scheduler/api" "yunion.io/x/onecloud/pkg/scheduler/core" + schedmodels "yunion.io/x/onecloud/pkg/scheduler/models" ) const ( @@ -47,7 +49,7 @@ type TaskExecutor struct { callback TaskExecuteCallback unit *core.Unit - resultItems *ScheduleResult + resultItems *core.ScheduleResult resultError error logs []string capacityMap interface{} @@ -81,16 +83,7 @@ func (te *TaskExecutor) Execute() { } } -type ScheduleResult struct { - // Result is sync schedule result - Result *schedapi.ScheduleOutput - // ForecastResult is forecast schedule result - ForecastResult interface{} - // TestResult is test schedule result - TestResult interface{} -} - -func (te *TaskExecutor) execute() (*ScheduleResult, error) { +func (te *TaskExecutor) execute() (*core.ScheduleResult, error) { scheduler := te.scheduler genericScheduler, err := core.NewGenericScheduler(scheduler.(core.Scheduler)) if err != nil { @@ -105,25 +98,43 @@ func (te *TaskExecutor) execute() (*ScheduleResult, error) { te.unit = scheduler.Unit() schedInfo := te.unit.SchedInfo - result, err := genericScheduler.Schedule(te.unit, candidates) + helper := GenerateResultHelper(schedInfo) + result, err := genericScheduler.Schedule(te.unit, candidates, helper) if err != nil { return nil, errors.Wrap(err, "genericScheduler.Schedule") } - out := new(ScheduleResult) if schedInfo.IsSuggestion { - if schedInfo.ShowSuggestionDetails && schedInfo.SuggestionAll { - out.ForecastResult = transToSchedForecastResult(result) - } else { - out.TestResult = transToSchedTestResult(result, schedInfo.SuggestionLimit) - } - } else { - out.Result = transToSchedResult(result, schedInfo) - driver := te.unit.GetHypervisorDriver() - if err := setSchedPendingUsage(driver, schedInfo, out.Result); err != nil { - return nil, errors.Wrap(err, "setSchedPendingUsage") - } + return result, nil } - return out, nil + driver := te.unit.GetHypervisorDriver() + if err := setSchedPendingUsage(driver, schedInfo, result.Result); err != nil { + return nil, errors.Wrap(err, "setSchedPendingUsage") + } + return result, nil +} + +func GenerateResultHelper(schedInfo *api.SchedInfo) core.IResultHelper { + if !schedInfo.IsSuggestion { + return core.SResultHelperFunc(core.ResultHelp) + } + if schedInfo.ShowSuggestionDetails && schedInfo.SuggestionAll { + return core.SResultHelperFunc(core.ResultHelpForForcast) + } + return core.SResultHelperFunc(core.ResultHelpForTest) +} + +func setSchedPendingUsage(driver computemodels.IGuestDriver, req *api.SchedInfo, resp *schedapi.ScheduleOutput) error { + if req.IsSuggestion || IsDriverSkipScheduleDirtyMark(driver) || req.SkipDirtyMarkHost() { + return nil + } + for _, item := range resp.Candidates { + schedmodels.HostPendingUsageManager.AddPendingUsage(req, item) + } + return nil +} + +func IsDriverSkipScheduleDirtyMark(driver computemodels.IGuestDriver) bool { + return !(driver.DoScheduleCPUFilter() && driver.DoScheduleMemoryFilter() && driver.DoScheduleStorageFilter()) } func (te *TaskExecutor) cleanup() { @@ -138,7 +149,7 @@ func (te *TaskExecutor) Kill() { } } -func (te *TaskExecutor) GetResult() (*ScheduleResult, error) { +func (te *TaskExecutor) GetResult() (*core.ScheduleResult, error) { return te.resultItems, te.resultError } @@ -299,7 +310,7 @@ type Task struct { waitCh chan struct{} completedCount int - resultItems *ScheduleResult + resultItems *core.ScheduleResult resultError error } @@ -393,12 +404,12 @@ func (t *Task) onCompleted() { close(t.waitCh) } -func (t *Task) Wait() (*ScheduleResult, error) { +func (t *Task) Wait() (*core.ScheduleResult, error) { log.V(10).Infof("Task wait...") <-t.waitCh return t.GetResult() } -func (t *Task) GetResult() (*ScheduleResult, error) { +func (t *Task) GetResult() (*core.ScheduleResult, error) { return t.resultItems, t.resultError }