talent-plan-tinykv/scheduler/server/schedule/scheduler.go
Connor 5e089a2cd1 init course framework
Signed-off-by: Connor <zbk602423539@gmail.com>
Co-authored-by: Nick Cameron <nrc@ncameron.org>
Co-authored-by: linning <linningde25@gmail.com>
Co-authored-by: YangKeao <keao.yang@yahoo.com>
Co-authored-by: andylokandy <andylokandy@hotmail.com>
Co-authored-by: Iosmanthus Teng <myosmanthustree@gmail.com>
2020-04-30 15:25:07 +08:00

140 lines
4.3 KiB
Go

// Copyright 2017 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.
package schedule
import (
"encoding/json"
"net/http"
"strings"
"time"
"github.com/pingcap-incubator/tinykv/scheduler/server/core"
"github.com/pingcap-incubator/tinykv/scheduler/server/schedule/operator"
"github.com/pingcap-incubator/tinykv/scheduler/server/schedule/opt"
"github.com/pingcap/log"
"github.com/pkg/errors"
"go.uber.org/zap"
)
// Scheduler is an interface to schedule resources.
type Scheduler interface {
http.Handler
GetName() string
// GetType should in accordance with the name passing to schedule.RegisterScheduler()
GetType() string
EncodeConfig() ([]byte, error)
GetMinInterval() time.Duration
GetNextInterval(interval time.Duration) time.Duration
Prepare(cluster opt.Cluster) error
Cleanup(cluster opt.Cluster)
Schedule(cluster opt.Cluster) *operator.Operator
IsScheduleAllowed(cluster opt.Cluster) bool
}
// EncodeConfig encode the custom config for each scheduler.
func EncodeConfig(v interface{}) ([]byte, error) {
return json.Marshal(v)
}
// DecodeConfig decode the custom config for each scheduler.
func DecodeConfig(data []byte, v interface{}) error {
return json.Unmarshal(data, v)
}
// ConfigDecoder used to decode the config.
type ConfigDecoder func(v interface{}) error
// ConfigSliceDecoderBuilder used to build slice decoder of the config.
type ConfigSliceDecoderBuilder func([]string) ConfigDecoder
//ConfigJSONDecoder used to build a json decoder of the config.
func ConfigJSONDecoder(data []byte) ConfigDecoder {
return func(v interface{}) error {
return DecodeConfig(data, v)
}
}
// ConfigSliceDecoder the default decode for the config.
func ConfigSliceDecoder(name string, args []string) ConfigDecoder {
builder, ok := schedulerArgsToDecoder[name]
if !ok {
return func(v interface{}) error {
return errors.Errorf("the config decoer do not register for %s", name)
}
}
return builder(args)
}
// CreateSchedulerFunc is for creating scheduler.
type CreateSchedulerFunc func(opController *OperatorController, storage *core.Storage, dec ConfigDecoder) (Scheduler, error)
var schedulerMap = make(map[string]CreateSchedulerFunc)
var schedulerArgsToDecoder = make(map[string]ConfigSliceDecoderBuilder)
// RegisterScheduler binds a scheduler creator. It should be called in init()
// func of a package.
func RegisterScheduler(typ string, createFn CreateSchedulerFunc) {
if _, ok := schedulerMap[typ]; ok {
log.Fatal("duplicated scheduler", zap.String("type", typ))
}
schedulerMap[typ] = createFn
}
// RegisterSliceDecoderBuilder convert arguments to config. It should be called in init()
// func of package.
func RegisterSliceDecoderBuilder(typ string, builder ConfigSliceDecoderBuilder) {
if _, ok := schedulerArgsToDecoder[typ]; ok {
log.Fatal("duplicated scheduler", zap.String("type", typ))
}
schedulerArgsToDecoder[typ] = builder
}
// IsSchedulerRegistered check where the named scheduler type is registered.
func IsSchedulerRegistered(name string) bool {
_, ok := schedulerMap[name]
return ok
}
// CreateScheduler creates a scheduler with registered creator func.
func CreateScheduler(typ string, opController *OperatorController, storage *core.Storage, dec ConfigDecoder) (Scheduler, error) {
fn, ok := schedulerMap[typ]
if !ok {
return nil, errors.Errorf("create func of %v is not registered", typ)
}
s, err := fn(opController, storage, dec)
if err != nil {
return nil, err
}
data, err := s.EncodeConfig()
if err != nil {
return nil, err
}
err = storage.SaveScheduleConfig(s.GetName(), data)
return s, err
}
// FindSchedulerTypeByName finds the type of the specified name.
func FindSchedulerTypeByName(name string) string {
var typ string
for registerdType := range schedulerMap {
if strings.Index(name, registerdType) != -1 {
if len(registerdType) > len(typ) {
typ = registerdType
}
}
}
return typ
}