|
|
|
@@ -15,28 +15,36 @@ |
|
|
|
package scheduler |
|
|
|
|
|
|
|
import ( |
|
|
|
"context" |
|
|
|
"encoding/json" |
|
|
|
"github.com/pkg/errors" |
|
|
|
"github.com/zeromicro/go-zero/core/logx" |
|
|
|
"gitlink.org.cn/jcce-pcm/pcm-coordinator/api/pkg/response" |
|
|
|
"gitlink.org.cn/jcce-pcm/pcm-coordinator/pkg/scheduler/algo" |
|
|
|
"gitlink.org.cn/jcce-pcm/pcm-coordinator/rpc/client/participantservice" |
|
|
|
"gorm.io/gorm" |
|
|
|
) |
|
|
|
|
|
|
|
type Replicas int64 |
|
|
|
|
|
|
|
type ParticipantId int64 |
|
|
|
|
|
|
|
type scheduler struct { |
|
|
|
task *response.TaskInfo |
|
|
|
participantIds []int64 |
|
|
|
scheduleService scheduleService |
|
|
|
dbEngin *gorm.DB |
|
|
|
result map[ParticipantId]Replicas |
|
|
|
participantRpc participantservice.ParticipantService |
|
|
|
} |
|
|
|
|
|
|
|
func NewScheduler(scheduleService scheduleService, val string, dbEngin *gorm.DB) (*scheduler, error) { |
|
|
|
func NewScheduler(scheduleService scheduleService, val string, dbEngin *gorm.DB, participantRpc participantservice.ParticipantService) (*scheduler, error) { |
|
|
|
var task *response.TaskInfo |
|
|
|
err := json.Unmarshal([]byte(val), &task) |
|
|
|
if err != nil { |
|
|
|
return nil, errors.New("create scheduler failed : " + err.Error()) |
|
|
|
} |
|
|
|
return &scheduler{task: task, scheduleService: scheduleService, dbEngin: dbEngin}, nil |
|
|
|
return &scheduler{task: task, scheduleService: scheduleService, dbEngin: dbEngin, participantRpc: participantRpc}, nil |
|
|
|
} |
|
|
|
|
|
|
|
func (s *scheduler) MatchLabels() { |
|
|
|
@@ -92,19 +100,10 @@ func (s *scheduler) AssignAndSchedule() error { |
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
//调度结果 ParticipantId |
|
|
|
for i, e := range strategy.ResourcePerTask { |
|
|
|
|
|
|
|
if len(e) != 0 { |
|
|
|
for _, ej := range e { |
|
|
|
if ej == 1 { |
|
|
|
s.task.ParticipantId = providerList[i].Pid |
|
|
|
break |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
continue |
|
|
|
} |
|
|
|
//调度结果 |
|
|
|
err = s.assignReplicasToResult(strategy, providerList) |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
return nil |
|
|
|
@@ -130,3 +129,65 @@ func (s *scheduler) SaveToDb() error { |
|
|
|
func (s *scheduler) obtainParamsforStrategy() (*algo.Task, []*algo.Provider) { |
|
|
|
return s.scheduleService.genTaskAndProviders(s.task, s.dbEngin) |
|
|
|
} |
|
|
|
|
|
|
|
func (s *scheduler) checkAvailableParticipants() error { |
|
|
|
resp, err := s.participantRpc.ListParticipant(context.Background(), nil) |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
if resp.Code != 200 { |
|
|
|
return errors.New("集群列表查询失败") |
|
|
|
} |
|
|
|
|
|
|
|
var workingIds []int64 |
|
|
|
for _, e := range resp.Data { |
|
|
|
if e.ClientState == "UNKNOWN" { |
|
|
|
continue |
|
|
|
} |
|
|
|
workingIds = append(workingIds, e.ParticipantId) |
|
|
|
} |
|
|
|
|
|
|
|
for id, _ := range s.result { |
|
|
|
if !contains(workingIds, int64(id)) { |
|
|
|
return errors.Errorf("集群 %d 不可用", id) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if len(s.result) == 0 { |
|
|
|
return errors.New("可用集群为空") |
|
|
|
} |
|
|
|
|
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
func (s *scheduler) assignReplicasToResult(strategy *algo.Strategy, providerList []*algo.Provider) error { |
|
|
|
|
|
|
|
if len(strategy.Tasksolution) == 0 { |
|
|
|
return errors.New("调度失败, 未能获取调度结果") |
|
|
|
} |
|
|
|
|
|
|
|
for i, e := range strategy.Tasksolution { |
|
|
|
if e == 0 { |
|
|
|
continue |
|
|
|
} |
|
|
|
s.result[ParticipantId(providerList[i].Pid)] = Replicas(e) |
|
|
|
} |
|
|
|
|
|
|
|
// 查询集群是否可用 |
|
|
|
err := s.checkAvailableParticipants() |
|
|
|
if err != nil { |
|
|
|
return err |
|
|
|
} |
|
|
|
|
|
|
|
return nil |
|
|
|
} |
|
|
|
|
|
|
|
func contains(s []int64, e int64) bool { |
|
|
|
for _, a := range s { |
|
|
|
if a == e { |
|
|
|
return true |
|
|
|
} |
|
|
|
} |
|
|
|
return false |
|
|
|
} |