Files
cloudpods/pkg/scheduler/factory/plugins.go
2019-03-29 14:47:48 +08:00

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
}