plugins.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package factory
  15. import (
  16. "fmt"
  17. "regexp"
  18. "sync"
  19. "yunion.io/x/log"
  20. "yunion.io/x/pkg/util/sets"
  21. "yunion.io/x/onecloud/pkg/scheduler/core"
  22. )
  23. type AlgorithmProviderConfig struct {
  24. FitPredicateKeys sets.String
  25. PriorityKeys sets.String
  26. }
  27. type FitPredicateFactory func() core.FitPredicate
  28. type PriorityFunctionFactory func() (core.PriorityPreFunction, core.PriorityMapFunction, core.PriorityReduceFunction)
  29. type PriorityConfigFactory struct {
  30. MapReduceFunction PriorityFunctionFactory
  31. Weight int
  32. }
  33. var (
  34. schedulerFactoryMutex sync.Mutex
  35. // maps that hold registered algorithm types
  36. fitPredicateMap = make(map[string]FitPredicateFactory)
  37. priorityConfigMap = make(map[string]PriorityConfigFactory)
  38. algorithmProviderMap = make(map[string]AlgorithmProviderConfig)
  39. validName = regexp.MustCompile("^[a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9])$")
  40. )
  41. const (
  42. DefaultProvider = "DefaultProvider"
  43. BaremetalProvider = "BaremetalProvider"
  44. )
  45. // RegisterAlgorithmProvider registers a new algorithm provider with the
  46. // algorithm registry. This shoud be called from the init function in a
  47. // provider plugin.
  48. func RegisterAlgorithmProvider(name string, predicatesKeys, priorityKeys sets.String) string {
  49. schedulerFactoryMutex.Lock()
  50. defer schedulerFactoryMutex.Unlock()
  51. validateAlgorithmNameOrDie(name)
  52. algorithmProviderMap[name] = AlgorithmProviderConfig{
  53. FitPredicateKeys: predicatesKeys,
  54. PriorityKeys: priorityKeys,
  55. }
  56. return name
  57. }
  58. func validateAlgorithmNameOrDie(name string) {
  59. if !validName.MatchString(name) {
  60. log.Fatalf("Algorithm name %v does not match the name validation regexp \"%v\".", name, validName)
  61. }
  62. }
  63. // RegisterFitPredicate registers a fit predicate with the algorithm
  64. // registry. Returns the name with which the predicates was registerd.
  65. func RegisterFitPredicate(name string, predicate core.FitPredicate) string {
  66. return RegisterFitPredicateFactory(name, func() core.FitPredicate { return predicate })
  67. }
  68. // RegisterFitPredicateFactory registers a fit predicate factory with the
  69. // algorithm registry. Returns the name with which the predicate was registered.
  70. func RegisterFitPredicateFactory(name string, predicateFactory FitPredicateFactory) string {
  71. schedulerFactoryMutex.Lock()
  72. defer schedulerFactoryMutex.Unlock()
  73. validateAlgorithmNameOrDie(name)
  74. fitPredicateMap[name] = predicateFactory
  75. return name
  76. }
  77. func getFitPredites(names sets.String) (map[string]core.FitPredicate, error) {
  78. schedulerFactoryMutex.Lock()
  79. defer schedulerFactoryMutex.Unlock()
  80. predicates := map[string]core.FitPredicate{}
  81. for _, name := range names.List() {
  82. factory, ok := fitPredicateMap[name]
  83. if !ok {
  84. return nil, fmt.Errorf("Invalid predicate name %q specified - no corresponding predicate found", name)
  85. }
  86. predicates[name] = factory()
  87. }
  88. return predicates, nil
  89. }
  90. // RegisterPriority registers a priority with the algorithm registry.
  91. func RegisterPriority(name string, priority core.Priority, weight int) string {
  92. schedulerFactoryMutex.Lock()
  93. defer schedulerFactoryMutex.Unlock()
  94. validateAlgorithmNameOrDie(name)
  95. priorityConfigMap[name] = PriorityConfigFactory{
  96. MapReduceFunction: func() (core.PriorityPreFunction, core.PriorityMapFunction, core.PriorityReduceFunction) {
  97. p := priority.Clone()
  98. return p.PreExecute, p.Map, p.Reduce
  99. },
  100. Weight: weight,
  101. }
  102. return name
  103. }
  104. func getPriorityConfigs(names sets.String) ([]core.PriorityConfig, error) {
  105. schedulerFactoryMutex.Lock()
  106. defer schedulerFactoryMutex.Unlock()
  107. configs := []core.PriorityConfig{}
  108. for _, name := range names.List() {
  109. factory, ok := priorityConfigMap[name]
  110. if !ok {
  111. return nil, fmt.Errorf("Invalid priority name %q specified - no corresponding priority found", name)
  112. }
  113. preFunc, mapFunc, reduceFunc := factory.MapReduceFunction()
  114. configs = append(configs, core.PriorityConfig{
  115. Pre: preFunc,
  116. Map: mapFunc,
  117. Reduce: reduceFunc,
  118. Weight: factory.Weight,
  119. })
  120. }
  121. return configs, nil
  122. }