mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-05-09 07:02:06 +08:00
145 lines
4.4 KiB
Go
145 lines
4.4 KiB
Go
// 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 factory
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"sync"
|
|
|
|
"yunion.io/x/log"
|
|
"yunion.io/x/pkg/util/sets"
|
|
|
|
"yunion.io/x/onecloud/pkg/scheduler/core"
|
|
)
|
|
|
|
type AlgorithmProviderConfig struct {
|
|
FitPredicateKeys sets.String
|
|
PriorityKeys sets.String
|
|
}
|
|
|
|
type FitPredicateFactory func() core.FitPredicate
|
|
|
|
type PriorityFunctionFactory func() (core.PriorityPreFunction, core.PriorityMapFunction, core.PriorityReduceFunction)
|
|
|
|
type PriorityConfigFactory struct {
|
|
MapReduceFunction PriorityFunctionFactory
|
|
Weight int
|
|
}
|
|
|
|
var (
|
|
schedulerFactoryMutex sync.Mutex
|
|
|
|
// maps that hold registered algorithm types
|
|
fitPredicateMap = make(map[string]FitPredicateFactory)
|
|
priorityConfigMap = make(map[string]PriorityConfigFactory)
|
|
algorithmProviderMap = make(map[string]AlgorithmProviderConfig)
|
|
|
|
validName = regexp.MustCompile("^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])$")
|
|
)
|
|
|
|
const (
|
|
DefaultProvider = "DefaultProvider"
|
|
BaremetalProvider = "BaremetalProvider"
|
|
)
|
|
|
|
// RegisterAlgorithmProvider registers a new algorithm provider with the
|
|
// algorithm registry. This shoud be called from the init function in a
|
|
// provider plugin.
|
|
func RegisterAlgorithmProvider(name string, predicatesKeys, priorityKeys sets.String) string {
|
|
schedulerFactoryMutex.Lock()
|
|
defer schedulerFactoryMutex.Unlock()
|
|
validateAlgorithmNameOrDie(name)
|
|
algorithmProviderMap[name] = AlgorithmProviderConfig{
|
|
FitPredicateKeys: predicatesKeys,
|
|
PriorityKeys: priorityKeys,
|
|
}
|
|
return name
|
|
}
|
|
|
|
func validateAlgorithmNameOrDie(name string) {
|
|
if !validName.MatchString(name) {
|
|
log.Fatalf("Algorithm name %v does not match the name validation regexp \"%v\".", name, validName)
|
|
}
|
|
|
|
}
|
|
|
|
// RegisterFitPredicate registers a fit predicate with the algorithm
|
|
// registry. Returns the name with which the predicates was registerd.
|
|
func RegisterFitPredicate(name string, predicate core.FitPredicate) string {
|
|
return RegisterFitPredicateFactory(name, func() core.FitPredicate { return predicate })
|
|
}
|
|
|
|
// RegisterFitPredicateFactory registers a fit predicate factory with the
|
|
// algorithm registry. Returns the name with which the predicate was registered.
|
|
func RegisterFitPredicateFactory(name string, predicateFactory FitPredicateFactory) string {
|
|
schedulerFactoryMutex.Lock()
|
|
defer schedulerFactoryMutex.Unlock()
|
|
validateAlgorithmNameOrDie(name)
|
|
fitPredicateMap[name] = predicateFactory
|
|
return name
|
|
}
|
|
|
|
func getFitPredites(names sets.String) (map[string]core.FitPredicate, error) {
|
|
schedulerFactoryMutex.Lock()
|
|
defer schedulerFactoryMutex.Unlock()
|
|
|
|
predicates := map[string]core.FitPredicate{}
|
|
for _, name := range names.List() {
|
|
factory, ok := fitPredicateMap[name]
|
|
if !ok {
|
|
return nil, fmt.Errorf("Invalid predicate name %q specified - no corresponding predicate found", name)
|
|
}
|
|
predicates[name] = factory()
|
|
}
|
|
return predicates, nil
|
|
}
|
|
|
|
// RegisterPriority registers a priority with the algorithm registry.
|
|
func RegisterPriority(name string, priority core.Priority, weight int) string {
|
|
schedulerFactoryMutex.Lock()
|
|
defer schedulerFactoryMutex.Unlock()
|
|
validateAlgorithmNameOrDie(name)
|
|
priorityConfigMap[name] = PriorityConfigFactory{
|
|
MapReduceFunction: func() (core.PriorityPreFunction, core.PriorityMapFunction, core.PriorityReduceFunction) {
|
|
p := priority.Clone()
|
|
return p.PreExecute, p.Map, p.Reduce
|
|
},
|
|
Weight: weight,
|
|
}
|
|
return name
|
|
}
|
|
|
|
func getPriorityConfigs(names sets.String) ([]core.PriorityConfig, error) {
|
|
schedulerFactoryMutex.Lock()
|
|
defer schedulerFactoryMutex.Unlock()
|
|
|
|
configs := []core.PriorityConfig{}
|
|
for _, name := range names.List() {
|
|
factory, ok := priorityConfigMap[name]
|
|
if !ok {
|
|
return nil, fmt.Errorf("Invalid priority name %q specified - no corresponding priority found", name)
|
|
}
|
|
preFunc, mapFunc, reduceFunc := factory.MapReduceFunction()
|
|
configs = append(configs, core.PriorityConfig{
|
|
Pre: preFunc,
|
|
Map: mapFunc,
|
|
Reduce: reduceFunc,
|
|
Weight: factory.Weight,
|
|
})
|
|
}
|
|
return configs, nil
|
|
}
|