2021-04-19 13:47:10 +08:00
|
|
|
// Copyright (C) 2019-2020 Zilliz. All rights reserved.
|
|
|
|
//
|
|
|
|
// 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.
|
|
|
|
|
2021-06-22 16:44:09 +08:00
|
|
|
package querycoord
|
2021-04-15 15:15:46 +08:00
|
|
|
|
|
|
|
import (
|
|
|
|
"container/list"
|
|
|
|
"context"
|
2021-06-19 11:45:09 +08:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"path/filepath"
|
|
|
|
"strconv"
|
2021-04-15 15:15:46 +08:00
|
|
|
"sync"
|
|
|
|
|
2021-06-19 11:45:09 +08:00
|
|
|
"github.com/golang/protobuf/proto"
|
2021-04-15 15:15:46 +08:00
|
|
|
"github.com/opentracing/opentracing-go"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
|
2021-06-19 11:45:09 +08:00
|
|
|
"github.com/milvus-io/milvus/internal/allocator"
|
2021-06-15 12:41:40 +08:00
|
|
|
etcdkv "github.com/milvus-io/milvus/internal/kv/etcd"
|
2021-04-22 14:45:57 +08:00
|
|
|
"github.com/milvus-io/milvus/internal/log"
|
2021-06-19 11:45:09 +08:00
|
|
|
"github.com/milvus-io/milvus/internal/proto/commonpb"
|
|
|
|
"github.com/milvus-io/milvus/internal/proto/querypb"
|
|
|
|
"github.com/milvus-io/milvus/internal/types"
|
2021-04-22 14:45:57 +08:00
|
|
|
"github.com/milvus-io/milvus/internal/util/trace"
|
2021-06-19 11:45:09 +08:00
|
|
|
"github.com/milvus-io/milvus/internal/util/tsoutil"
|
2021-04-15 15:15:46 +08:00
|
|
|
oplog "github.com/opentracing/opentracing-go/log"
|
|
|
|
)
|
|
|
|
|
2021-10-08 23:58:22 +08:00
|
|
|
// TaskQueue is used to cache triggerTasks
|
2021-06-15 12:41:40 +08:00
|
|
|
type TaskQueue struct {
|
|
|
|
tasks *list.List
|
2021-04-15 15:15:46 +08:00
|
|
|
|
2021-06-15 12:41:40 +08:00
|
|
|
maxTask int64
|
|
|
|
taskChan chan int // to block scheduler
|
2021-04-15 15:15:46 +08:00
|
|
|
|
2021-06-15 12:41:40 +08:00
|
|
|
sync.Mutex
|
2021-04-15 15:15:46 +08:00
|
|
|
}
|
|
|
|
|
2021-10-11 21:42:33 +08:00
|
|
|
// Chan returns the taskChan of taskQueue
|
2021-06-15 12:41:40 +08:00
|
|
|
func (queue *TaskQueue) Chan() <-chan int {
|
|
|
|
return queue.taskChan
|
2021-04-15 15:15:46 +08:00
|
|
|
}
|
|
|
|
|
2021-06-15 12:41:40 +08:00
|
|
|
func (queue *TaskQueue) taskEmpty() bool {
|
|
|
|
queue.Lock()
|
|
|
|
defer queue.Unlock()
|
|
|
|
return queue.tasks.Len() == 0
|
2021-04-15 15:15:46 +08:00
|
|
|
}
|
|
|
|
|
2021-06-15 12:41:40 +08:00
|
|
|
func (queue *TaskQueue) taskFull() bool {
|
|
|
|
return int64(queue.tasks.Len()) >= queue.maxTask
|
2021-04-15 15:15:46 +08:00
|
|
|
}
|
|
|
|
|
2021-10-11 09:54:37 +08:00
|
|
|
func (queue *TaskQueue) addTask(t task) {
|
2021-06-15 12:41:40 +08:00
|
|
|
queue.Lock()
|
|
|
|
defer queue.Unlock()
|
2021-04-15 15:15:46 +08:00
|
|
|
|
2021-10-11 09:54:37 +08:00
|
|
|
if queue.tasks.Len() == 0 {
|
|
|
|
queue.taskChan <- 1
|
|
|
|
queue.tasks.PushBack(t)
|
|
|
|
return
|
|
|
|
}
|
2021-04-15 15:15:46 +08:00
|
|
|
|
2021-10-11 09:54:37 +08:00
|
|
|
for e := queue.tasks.Back(); e != nil; e = e.Prev() {
|
|
|
|
if t.TaskPriority() > e.Value.(task).TaskPriority() {
|
|
|
|
if e.Prev() == nil {
|
|
|
|
queue.taskChan <- 1
|
|
|
|
queue.tasks.InsertBefore(t, e)
|
|
|
|
break
|
2021-06-15 12:41:40 +08:00
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
continue
|
2021-06-15 12:41:40 +08:00
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
//TODO:: take care of timestamp
|
|
|
|
queue.taskChan <- 1
|
|
|
|
queue.tasks.InsertAfter(t, e)
|
|
|
|
break
|
2021-04-15 15:15:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-19 11:45:09 +08:00
|
|
|
func (queue *TaskQueue) addTaskToFront(t task) {
|
|
|
|
queue.taskChan <- 1
|
|
|
|
if queue.tasks.Len() == 0 {
|
|
|
|
queue.tasks.PushBack(t)
|
|
|
|
} else {
|
|
|
|
queue.tasks.PushFront(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-09 20:19:10 +08:00
|
|
|
// PopTask pops a trigger task from task list
|
2021-06-15 12:41:40 +08:00
|
|
|
func (queue *TaskQueue) PopTask() task {
|
|
|
|
queue.Lock()
|
|
|
|
defer queue.Unlock()
|
2021-04-15 15:15:46 +08:00
|
|
|
|
2021-06-15 12:41:40 +08:00
|
|
|
if queue.tasks.Len() <= 0 {
|
2021-04-15 15:15:46 +08:00
|
|
|
log.Warn("sorry, but the unissued task list is empty!")
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-06-15 12:41:40 +08:00
|
|
|
ft := queue.tasks.Front()
|
|
|
|
queue.tasks.Remove(ft)
|
2021-04-15 15:15:46 +08:00
|
|
|
|
|
|
|
return ft.Value.(task)
|
|
|
|
}
|
|
|
|
|
2021-10-09 00:00:17 +08:00
|
|
|
// NewTaskQueue creates a new task queue for scheduler to cache trigger tasks
|
2021-06-19 11:45:09 +08:00
|
|
|
func NewTaskQueue() *TaskQueue {
|
2021-06-15 12:41:40 +08:00
|
|
|
return &TaskQueue{
|
2021-06-19 11:45:09 +08:00
|
|
|
tasks: list.New(),
|
|
|
|
maxTask: 1024,
|
|
|
|
taskChan: make(chan int, 1024),
|
2021-04-15 15:15:46 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-09 00:02:09 +08:00
|
|
|
// TaskScheduler controls the scheduling of trigger tasks and internal tasks
|
2021-04-15 15:15:46 +08:00
|
|
|
type TaskScheduler struct {
|
2021-10-11 09:54:37 +08:00
|
|
|
triggerTaskQueue *TaskQueue
|
|
|
|
activateTaskChan chan task
|
|
|
|
meta Meta
|
|
|
|
cluster Cluster
|
|
|
|
taskIDAllocator func() (UniqueID, error)
|
|
|
|
client *etcdkv.EtcdKV
|
|
|
|
stopActivateTaskLoopChan chan int
|
2021-06-19 11:45:09 +08:00
|
|
|
|
2021-06-21 18:22:13 +08:00
|
|
|
rootCoord types.RootCoord
|
|
|
|
dataCoord types.DataCoord
|
2021-04-15 15:15:46 +08:00
|
|
|
|
|
|
|
wg sync.WaitGroup
|
|
|
|
ctx context.Context
|
|
|
|
cancel context.CancelFunc
|
|
|
|
}
|
|
|
|
|
2021-10-11 21:08:30 +08:00
|
|
|
// NewTaskScheduler reloads tasks from kv and returns a new taskScheduler
|
2021-09-15 20:40:07 +08:00
|
|
|
func NewTaskScheduler(ctx context.Context, meta Meta, cluster Cluster, kv *etcdkv.EtcdKV, rootCoord types.RootCoord, dataCoord types.DataCoord) (*TaskScheduler, error) {
|
2021-04-15 15:15:46 +08:00
|
|
|
ctx1, cancel := context.WithCancel(ctx)
|
2021-06-15 12:41:40 +08:00
|
|
|
taskChan := make(chan task, 1024)
|
2021-10-11 09:54:37 +08:00
|
|
|
stopTaskLoopChan := make(chan int, 1)
|
2021-04-15 15:15:46 +08:00
|
|
|
s := &TaskScheduler{
|
2021-10-11 09:54:37 +08:00
|
|
|
ctx: ctx1,
|
|
|
|
cancel: cancel,
|
|
|
|
meta: meta,
|
|
|
|
cluster: cluster,
|
|
|
|
activateTaskChan: taskChan,
|
|
|
|
client: kv,
|
|
|
|
stopActivateTaskLoopChan: stopTaskLoopChan,
|
|
|
|
rootCoord: rootCoord,
|
|
|
|
dataCoord: dataCoord,
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
s.triggerTaskQueue = NewTaskQueue()
|
2021-10-11 09:54:37 +08:00
|
|
|
//init id allocator
|
2021-08-13 11:04:09 +08:00
|
|
|
etcdKV, err := tsoutil.NewTSOKVBase(Params.EtcdEndpoints, Params.KvRootPath, "queryCoordTaskID")
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
idAllocator := allocator.NewGlobalIDAllocator("idTimestamp", etcdKV)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err := idAllocator.Initialize(); err != nil {
|
2021-06-22 16:44:09 +08:00
|
|
|
log.Debug("query coordinator idAllocator initialize failed", zap.Error(err))
|
2021-06-19 11:45:09 +08:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
s.taskIDAllocator = func() (UniqueID, error) {
|
|
|
|
return idAllocator.AllocOne()
|
|
|
|
}
|
2021-08-13 11:04:09 +08:00
|
|
|
err = s.reloadFromKV()
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
2021-10-11 09:54:37 +08:00
|
|
|
log.Error("reload task from kv failed", zap.Error(err))
|
2021-06-19 11:45:09 +08:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return s, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (scheduler *TaskScheduler) reloadFromKV() error {
|
|
|
|
triggerTaskIDKeys, triggerTaskValues, err := scheduler.client.LoadWithPrefix(triggerTaskPrefix)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
activeTaskIDKeys, activeTaskValues, err := scheduler.client.LoadWithPrefix(activeTaskPrefix)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
taskInfoKeys, taskInfoValues, err := scheduler.client.LoadWithPrefix(taskInfoPrefix)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
triggerTasks := make(map[int64]task)
|
|
|
|
for index := range triggerTaskIDKeys {
|
|
|
|
taskID, err := strconv.ParseInt(filepath.Base(triggerTaskIDKeys[index]), 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
t, err := scheduler.unmarshalTask(taskID, triggerTaskValues[index])
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
triggerTasks[taskID] = t
|
|
|
|
}
|
|
|
|
|
|
|
|
activeTasks := make(map[int64]task)
|
|
|
|
for index := range activeTaskIDKeys {
|
|
|
|
taskID, err := strconv.ParseInt(filepath.Base(activeTaskIDKeys[index]), 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
t, err := scheduler.unmarshalTask(taskID, activeTaskValues[index])
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
activeTasks[taskID] = t
|
|
|
|
}
|
|
|
|
|
|
|
|
taskInfos := make(map[int64]taskState)
|
|
|
|
for index := range taskInfoKeys {
|
|
|
|
taskID, err := strconv.ParseInt(filepath.Base(taskInfoKeys[index]), 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
value, err := strconv.ParseInt(taskInfoValues[index], 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
state := taskState(value)
|
|
|
|
taskInfos[taskID] = state
|
2021-08-02 22:39:25 +08:00
|
|
|
if _, ok := triggerTasks[taskID]; !ok {
|
2021-08-03 22:03:25 +08:00
|
|
|
log.Error("reloadFromKV: taskStateInfo and triggerTaskInfo are inconsistent")
|
|
|
|
continue
|
2021-08-02 22:39:25 +08:00
|
|
|
}
|
|
|
|
triggerTasks[taskID].SetState(state)
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
var doneTriggerTask task = nil
|
2021-10-11 09:54:37 +08:00
|
|
|
for _, t := range triggerTasks {
|
|
|
|
if t.State() == taskDone {
|
2021-06-19 11:45:09 +08:00
|
|
|
doneTriggerTask = t
|
|
|
|
for _, childTask := range activeTasks {
|
2021-10-11 09:54:37 +08:00
|
|
|
childTask.SetParentTask(t) //replace child task after reScheduler
|
2021-06-19 11:45:09 +08:00
|
|
|
t.AddChildTask(childTask)
|
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
t.SetResultInfo(nil)
|
2021-06-19 11:45:09 +08:00
|
|
|
continue
|
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
scheduler.triggerTaskQueue.addTask(t)
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if doneTriggerTask != nil {
|
|
|
|
scheduler.triggerTaskQueue.addTaskToFront(doneTriggerTask)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-10-11 09:54:37 +08:00
|
|
|
func (scheduler *TaskScheduler) unmarshalTask(taskID UniqueID, t string) (task, error) {
|
2021-06-19 11:45:09 +08:00
|
|
|
header := commonpb.MsgHeader{}
|
2021-08-03 22:03:25 +08:00
|
|
|
err := proto.Unmarshal([]byte(t), &header)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("Failed to unmarshal message header, err %s ", err.Error())
|
|
|
|
}
|
|
|
|
var newTask task
|
2021-10-11 09:54:37 +08:00
|
|
|
baseTask := newBaseTask(scheduler.ctx, querypb.TriggerCondition_grpcRequest)
|
2021-06-19 11:45:09 +08:00
|
|
|
switch header.Base.MsgType {
|
|
|
|
case commonpb.MsgType_LoadCollection:
|
|
|
|
loadReq := querypb.LoadCollectionRequest{}
|
2021-08-03 22:03:25 +08:00
|
|
|
err = proto.Unmarshal([]byte(t), &loadReq)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
2021-10-11 09:54:37 +08:00
|
|
|
return nil, err
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
loadCollectionTask := &LoadCollectionTask{
|
2021-10-11 09:54:37 +08:00
|
|
|
BaseTask: baseTask,
|
2021-06-19 11:45:09 +08:00
|
|
|
LoadCollectionRequest: &loadReq,
|
2021-06-21 17:28:03 +08:00
|
|
|
rootCoord: scheduler.rootCoord,
|
2021-06-21 18:22:13 +08:00
|
|
|
dataCoord: scheduler.dataCoord,
|
2021-06-19 11:45:09 +08:00
|
|
|
cluster: scheduler.cluster,
|
|
|
|
meta: scheduler.meta,
|
|
|
|
}
|
|
|
|
newTask = loadCollectionTask
|
|
|
|
case commonpb.MsgType_LoadPartitions:
|
|
|
|
loadReq := querypb.LoadPartitionsRequest{}
|
2021-08-03 22:03:25 +08:00
|
|
|
err = proto.Unmarshal([]byte(t), &loadReq)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
2021-10-11 09:54:37 +08:00
|
|
|
return nil, err
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
loadPartitionTask := &LoadPartitionTask{
|
2021-10-11 09:54:37 +08:00
|
|
|
BaseTask: baseTask,
|
2021-06-19 11:45:09 +08:00
|
|
|
LoadPartitionsRequest: &loadReq,
|
2021-06-21 18:22:13 +08:00
|
|
|
dataCoord: scheduler.dataCoord,
|
2021-06-19 11:45:09 +08:00
|
|
|
cluster: scheduler.cluster,
|
|
|
|
meta: scheduler.meta,
|
|
|
|
}
|
|
|
|
newTask = loadPartitionTask
|
|
|
|
case commonpb.MsgType_ReleaseCollection:
|
|
|
|
loadReq := querypb.ReleaseCollectionRequest{}
|
2021-08-03 22:03:25 +08:00
|
|
|
err = proto.Unmarshal([]byte(t), &loadReq)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
2021-10-11 09:54:37 +08:00
|
|
|
return nil, err
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
releaseCollectionTask := &ReleaseCollectionTask{
|
2021-10-11 09:54:37 +08:00
|
|
|
BaseTask: baseTask,
|
2021-06-19 11:45:09 +08:00
|
|
|
ReleaseCollectionRequest: &loadReq,
|
|
|
|
cluster: scheduler.cluster,
|
2021-07-02 10:40:13 +08:00
|
|
|
meta: scheduler.meta,
|
|
|
|
rootCoord: scheduler.rootCoord,
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
newTask = releaseCollectionTask
|
|
|
|
case commonpb.MsgType_ReleasePartitions:
|
|
|
|
loadReq := querypb.ReleasePartitionsRequest{}
|
2021-08-03 22:03:25 +08:00
|
|
|
err = proto.Unmarshal([]byte(t), &loadReq)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
2021-10-11 09:54:37 +08:00
|
|
|
return nil, err
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
releasePartitionTask := &ReleasePartitionTask{
|
2021-10-11 09:54:37 +08:00
|
|
|
BaseTask: baseTask,
|
2021-06-19 11:45:09 +08:00
|
|
|
ReleasePartitionsRequest: &loadReq,
|
|
|
|
cluster: scheduler.cluster,
|
|
|
|
}
|
|
|
|
newTask = releasePartitionTask
|
|
|
|
case commonpb.MsgType_LoadSegments:
|
2021-10-11 09:54:37 +08:00
|
|
|
//TODO::trigger condition may be different
|
2021-06-19 11:45:09 +08:00
|
|
|
loadReq := querypb.LoadSegmentsRequest{}
|
2021-08-03 22:03:25 +08:00
|
|
|
err = proto.Unmarshal([]byte(t), &loadReq)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
2021-10-11 09:54:37 +08:00
|
|
|
return nil, err
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
loadSegmentTask := &LoadSegmentTask{
|
2021-10-11 09:54:37 +08:00
|
|
|
BaseTask: baseTask,
|
2021-06-19 11:45:09 +08:00
|
|
|
LoadSegmentsRequest: &loadReq,
|
|
|
|
cluster: scheduler.cluster,
|
|
|
|
meta: scheduler.meta,
|
2021-10-11 09:54:37 +08:00
|
|
|
excludeNodeIDs: []int64{},
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
newTask = loadSegmentTask
|
|
|
|
case commonpb.MsgType_ReleaseSegments:
|
2021-10-11 09:54:37 +08:00
|
|
|
//TODO::trigger condition may be different
|
2021-06-19 11:45:09 +08:00
|
|
|
loadReq := querypb.ReleaseSegmentsRequest{}
|
2021-08-03 22:03:25 +08:00
|
|
|
err = proto.Unmarshal([]byte(t), &loadReq)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
2021-10-11 09:54:37 +08:00
|
|
|
return nil, err
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
releaseSegmentTask := &ReleaseSegmentTask{
|
2021-10-11 09:54:37 +08:00
|
|
|
BaseTask: baseTask,
|
2021-06-19 11:45:09 +08:00
|
|
|
ReleaseSegmentsRequest: &loadReq,
|
|
|
|
cluster: scheduler.cluster,
|
|
|
|
}
|
|
|
|
newTask = releaseSegmentTask
|
|
|
|
case commonpb.MsgType_WatchDmChannels:
|
2021-10-11 09:54:37 +08:00
|
|
|
//TODO::trigger condition may be different
|
2021-06-19 11:45:09 +08:00
|
|
|
loadReq := querypb.WatchDmChannelsRequest{}
|
2021-08-03 22:03:25 +08:00
|
|
|
err = proto.Unmarshal([]byte(t), &loadReq)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
2021-10-11 09:54:37 +08:00
|
|
|
return nil, err
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
watchDmChannelTask := &WatchDmChannelTask{
|
2021-10-11 09:54:37 +08:00
|
|
|
BaseTask: baseTask,
|
2021-06-19 11:45:09 +08:00
|
|
|
WatchDmChannelsRequest: &loadReq,
|
|
|
|
cluster: scheduler.cluster,
|
|
|
|
meta: scheduler.meta,
|
2021-10-11 09:54:37 +08:00
|
|
|
excludeNodeIDs: []int64{},
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
newTask = watchDmChannelTask
|
|
|
|
case commonpb.MsgType_WatchQueryChannels:
|
2021-10-11 09:54:37 +08:00
|
|
|
//TODO::trigger condition may be different
|
2021-06-19 11:45:09 +08:00
|
|
|
loadReq := querypb.AddQueryChannelRequest{}
|
2021-08-03 22:03:25 +08:00
|
|
|
err = proto.Unmarshal([]byte(t), &loadReq)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
2021-10-11 09:54:37 +08:00
|
|
|
return nil, err
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
watchQueryChannelTask := &WatchQueryChannelTask{
|
2021-10-11 09:54:37 +08:00
|
|
|
BaseTask: baseTask,
|
2021-06-19 11:45:09 +08:00
|
|
|
AddQueryChannelRequest: &loadReq,
|
|
|
|
cluster: scheduler.cluster,
|
|
|
|
}
|
|
|
|
newTask = watchQueryChannelTask
|
|
|
|
case commonpb.MsgType_LoadBalanceSegments:
|
2021-10-11 09:54:37 +08:00
|
|
|
//TODO::trigger condition may be different
|
2021-06-19 11:45:09 +08:00
|
|
|
loadReq := querypb.LoadBalanceRequest{}
|
2021-08-03 22:03:25 +08:00
|
|
|
err = proto.Unmarshal([]byte(t), &loadReq)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
2021-10-11 09:54:37 +08:00
|
|
|
return nil, err
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
loadBalanceTask := &LoadBalanceTask{
|
2021-10-11 09:54:37 +08:00
|
|
|
BaseTask: baseTask,
|
2021-06-19 11:45:09 +08:00
|
|
|
LoadBalanceRequest: &loadReq,
|
2021-06-21 17:28:03 +08:00
|
|
|
rootCoord: scheduler.rootCoord,
|
2021-06-21 18:22:13 +08:00
|
|
|
dataCoord: scheduler.dataCoord,
|
2021-06-19 11:45:09 +08:00
|
|
|
cluster: scheduler.cluster,
|
|
|
|
meta: scheduler.meta,
|
|
|
|
}
|
|
|
|
newTask = loadBalanceTask
|
|
|
|
default:
|
|
|
|
err = errors.New("inValid msg type when unMarshal task")
|
|
|
|
log.Error(err.Error())
|
|
|
|
return nil, err
|
2021-04-15 15:15:46 +08:00
|
|
|
}
|
|
|
|
|
2021-10-11 09:54:37 +08:00
|
|
|
newTask.SetID(taskID)
|
2021-06-19 11:45:09 +08:00
|
|
|
return newTask, nil
|
2021-04-15 15:15:46 +08:00
|
|
|
}
|
|
|
|
|
2021-10-09 19:54:16 +08:00
|
|
|
// Enqueue pushs a trigger task to triggerTaskQueue and assigns task id
|
2021-10-11 09:54:37 +08:00
|
|
|
func (scheduler *TaskScheduler) Enqueue(t task) error {
|
|
|
|
id, err := scheduler.taskIDAllocator()
|
|
|
|
if err != nil {
|
|
|
|
log.Error("allocator trigger taskID failed", zap.Error(err))
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
t.SetID(id)
|
|
|
|
kvs := make(map[string]string)
|
|
|
|
taskKey := fmt.Sprintf("%s/%d", triggerTaskPrefix, t.ID())
|
|
|
|
blobs, err := t.Marshal()
|
|
|
|
if err != nil {
|
|
|
|
log.Error("error when save marshal task", zap.Int64("taskID", t.ID()), zap.Error(err))
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
kvs[taskKey] = string(blobs)
|
|
|
|
stateKey := fmt.Sprintf("%s/%d", taskInfoPrefix, t.ID())
|
|
|
|
kvs[stateKey] = strconv.Itoa(int(taskUndo))
|
|
|
|
err = scheduler.client.MultiSave(kvs)
|
|
|
|
if err != nil {
|
|
|
|
//TODO::clean etcd meta
|
|
|
|
log.Error("error when save trigger task to etcd", zap.Int64("taskID", t.ID()), zap.Error(err))
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
t.SetState(taskUndo)
|
|
|
|
scheduler.triggerTaskQueue.addTask(t)
|
|
|
|
log.Debug("EnQueue a triggerTask and save to etcd", zap.Int64("taskID", t.ID()))
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (scheduler *TaskScheduler) processTask(t task) error {
|
|
|
|
var taskInfoKey string
|
|
|
|
// assign taskID for childTask and update triggerTask's childTask to etcd
|
|
|
|
updateKVFn := func(parentTask task) error {
|
2021-06-19 11:45:09 +08:00
|
|
|
kvs := make(map[string]string)
|
2021-10-11 09:54:37 +08:00
|
|
|
kvs[taskInfoKey] = strconv.Itoa(int(taskDone))
|
|
|
|
for _, childTask := range parentTask.GetChildTask() {
|
|
|
|
id, err := scheduler.taskIDAllocator()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
childTask.SetID(id)
|
|
|
|
childTaskKey := fmt.Sprintf("%s/%d", activeTaskPrefix, childTask.ID())
|
|
|
|
blobs, err := childTask.Marshal()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
kvs[childTaskKey] = string(blobs)
|
|
|
|
stateKey := fmt.Sprintf("%s/%d", taskInfoPrefix, childTask.ID())
|
|
|
|
kvs[stateKey] = strconv.Itoa(int(taskUndo))
|
2021-08-03 22:03:25 +08:00
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
err := scheduler.client.MultiSave(kvs)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
2021-10-11 09:54:37 +08:00
|
|
|
return err
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
return nil
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
|
2021-04-15 15:15:46 +08:00
|
|
|
span, ctx := trace.StartSpanFromContext(t.TraceCtx(),
|
|
|
|
opentracing.Tags{
|
2021-06-15 12:41:40 +08:00
|
|
|
"Type": t.Type(),
|
2021-04-15 15:15:46 +08:00
|
|
|
"ID": t.ID(),
|
|
|
|
})
|
2021-10-11 09:54:37 +08:00
|
|
|
var err error
|
2021-04-15 15:15:46 +08:00
|
|
|
defer span.Finish()
|
2021-10-11 09:54:37 +08:00
|
|
|
|
|
|
|
defer func() {
|
|
|
|
//task postExecute
|
|
|
|
span.LogFields(oplog.Int64("processTask: scheduler process PostExecute", t.ID()))
|
|
|
|
t.PostExecute(ctx)
|
|
|
|
}()
|
|
|
|
|
|
|
|
// task preExecute
|
2021-06-19 11:45:09 +08:00
|
|
|
span.LogFields(oplog.Int64("processTask: scheduler process PreExecute", t.ID()))
|
2021-06-30 16:18:13 +08:00
|
|
|
t.PreExecute(ctx)
|
2021-10-11 09:54:37 +08:00
|
|
|
taskInfoKey = fmt.Sprintf("%s/%d", taskInfoPrefix, t.ID())
|
|
|
|
err = scheduler.client.Save(taskInfoKey, strconv.Itoa(int(taskDoing)))
|
2021-04-15 15:15:46 +08:00
|
|
|
if err != nil {
|
|
|
|
trace.LogError(span, err)
|
2021-10-11 09:54:37 +08:00
|
|
|
t.SetResultInfo(err)
|
2021-06-19 11:45:09 +08:00
|
|
|
return err
|
2021-04-15 15:15:46 +08:00
|
|
|
}
|
2021-08-02 22:39:25 +08:00
|
|
|
t.SetState(taskDoing)
|
2021-04-15 15:15:46 +08:00
|
|
|
|
2021-10-11 09:54:37 +08:00
|
|
|
// task execute
|
2021-06-19 11:45:09 +08:00
|
|
|
span.LogFields(oplog.Int64("processTask: scheduler process Execute", t.ID()))
|
2021-04-15 15:15:46 +08:00
|
|
|
err = t.Execute(ctx)
|
|
|
|
if err != nil {
|
|
|
|
trace.LogError(span, err)
|
2021-06-19 11:45:09 +08:00
|
|
|
return err
|
2021-04-15 15:15:46 +08:00
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
err = updateKVFn(t)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
|
|
|
trace.LogError(span, err)
|
2021-10-11 09:54:37 +08:00
|
|
|
t.SetResultInfo(err)
|
2021-06-19 11:45:09 +08:00
|
|
|
return err
|
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
log.Debug("processTask: update etcd success", zap.Int64("parent taskID", t.ID()))
|
|
|
|
if t.Type() == commonpb.MsgType_LoadCollection || t.Type() == commonpb.MsgType_LoadPartitions {
|
|
|
|
t.Notify(nil)
|
|
|
|
}
|
2021-06-23 17:44:12 +08:00
|
|
|
|
2021-08-02 22:39:25 +08:00
|
|
|
t.SetState(taskDone)
|
2021-10-11 09:54:37 +08:00
|
|
|
t.UpdateTaskProcess()
|
2021-06-23 17:44:12 +08:00
|
|
|
|
|
|
|
return nil
|
2021-04-15 15:15:46 +08:00
|
|
|
}
|
|
|
|
|
2021-06-15 12:41:40 +08:00
|
|
|
func (scheduler *TaskScheduler) scheduleLoop() {
|
|
|
|
defer scheduler.wg.Done()
|
2021-06-19 11:45:09 +08:00
|
|
|
activeTaskWg := &sync.WaitGroup{}
|
2021-10-11 09:54:37 +08:00
|
|
|
var triggerTask task
|
|
|
|
|
|
|
|
processInternalTaskFn := func(activateTasks []task, triggerTask task) {
|
|
|
|
log.Debug("scheduleLoop: num of child task", zap.Int("num child task", len(activateTasks)))
|
|
|
|
for _, childTask := range activateTasks {
|
|
|
|
if childTask != nil {
|
|
|
|
log.Debug("scheduleLoop: add a activate task to activateChan", zap.Int64("taskID", childTask.ID()))
|
|
|
|
scheduler.activateTaskChan <- childTask
|
|
|
|
activeTaskWg.Add(1)
|
|
|
|
go scheduler.waitActivateTaskDone(activeTaskWg, childTask, triggerTask)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
activeTaskWg.Wait()
|
|
|
|
}
|
|
|
|
|
|
|
|
rollBackInterTaskFn := func(triggerTask task, originInternalTasks []task, rollBackTasks []task) error {
|
|
|
|
saves := make(map[string]string)
|
|
|
|
removes := make([]string, 0)
|
|
|
|
childTaskIDs := make([]int64, 0)
|
|
|
|
for _, t := range originInternalTasks {
|
|
|
|
childTaskIDs = append(childTaskIDs, t.ID())
|
|
|
|
taskKey := fmt.Sprintf("%s/%d", activeTaskPrefix, t.ID())
|
|
|
|
removes = append(removes, taskKey)
|
|
|
|
stateKey := fmt.Sprintf("%s/%d", taskInfoPrefix, t.ID())
|
|
|
|
removes = append(removes, stateKey)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, t := range rollBackTasks {
|
|
|
|
id, err := scheduler.taskIDAllocator()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
t.SetID(id)
|
|
|
|
taskKey := fmt.Sprintf("%s/%d", activeTaskPrefix, t.ID())
|
|
|
|
blobs, err := t.Marshal()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
saves[taskKey] = string(blobs)
|
|
|
|
stateKey := fmt.Sprintf("%s/%d", taskInfoPrefix, t.ID())
|
|
|
|
saves[stateKey] = strconv.Itoa(int(taskUndo))
|
|
|
|
}
|
|
|
|
|
|
|
|
err := scheduler.client.MultiSaveAndRemove(saves, removes)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
for _, taskID := range childTaskIDs {
|
|
|
|
triggerTask.RemoveChildTaskByID(taskID)
|
|
|
|
}
|
|
|
|
for _, t := range rollBackTasks {
|
|
|
|
triggerTask.AddChildTask(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
removeTaskFromKVFn := func(triggerTask task) error {
|
|
|
|
keys := make([]string, 0)
|
|
|
|
taskKey := fmt.Sprintf("%s/%d", triggerTaskPrefix, triggerTask.ID())
|
|
|
|
stateKey := fmt.Sprintf("%s/%d", taskInfoPrefix, triggerTask.ID())
|
|
|
|
keys = append(keys, taskKey)
|
|
|
|
keys = append(keys, stateKey)
|
|
|
|
childTasks := triggerTask.GetChildTask()
|
|
|
|
for _, t := range childTasks {
|
|
|
|
taskKey = fmt.Sprintf("%s/%d", activeTaskPrefix, t.ID())
|
|
|
|
stateKey = fmt.Sprintf("%s/%d", taskInfoPrefix, t.ID())
|
|
|
|
keys = append(keys, taskKey)
|
|
|
|
keys = append(keys, stateKey)
|
|
|
|
}
|
|
|
|
err := scheduler.client.MultiRemove(keys)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2021-06-22 14:10:09 +08:00
|
|
|
|
2021-04-15 15:15:46 +08:00
|
|
|
for {
|
2021-10-11 09:54:37 +08:00
|
|
|
var err error
|
2021-04-15 15:15:46 +08:00
|
|
|
select {
|
2021-06-15 12:41:40 +08:00
|
|
|
case <-scheduler.ctx.Done():
|
2021-10-11 09:54:37 +08:00
|
|
|
scheduler.stopActivateTaskLoopChan <- 1
|
2021-04-15 15:15:46 +08:00
|
|
|
return
|
2021-06-15 12:41:40 +08:00
|
|
|
case <-scheduler.triggerTaskQueue.Chan():
|
2021-10-11 09:54:37 +08:00
|
|
|
triggerTask = scheduler.triggerTaskQueue.PopTask()
|
|
|
|
log.Debug("scheduleLoop: pop a triggerTask from triggerTaskQueue", zap.Int64("triggerTaskID", triggerTask.ID()))
|
|
|
|
alreadyNotify := true
|
|
|
|
if triggerTask.State() == taskUndo || triggerTask.State() == taskDoing {
|
|
|
|
err = scheduler.processTask(triggerTask)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
2021-10-11 09:54:37 +08:00
|
|
|
log.Debug("scheduleLoop: process triggerTask failed", zap.Int64("triggerTaskID", triggerTask.ID()), zap.Error(err))
|
|
|
|
alreadyNotify = false
|
2021-06-21 19:20:31 +08:00
|
|
|
}
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
if triggerTask.Type() != commonpb.MsgType_LoadCollection && triggerTask.Type() != commonpb.MsgType_LoadPartitions {
|
|
|
|
alreadyNotify = false
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
|
|
|
|
childTasks := triggerTask.GetChildTask()
|
|
|
|
if len(childTasks) != 0 {
|
|
|
|
activateTasks := make([]task, len(childTasks))
|
|
|
|
copy(activateTasks, childTasks)
|
|
|
|
processInternalTaskFn(activateTasks, triggerTask)
|
|
|
|
resultStatus := triggerTask.GetResultInfo()
|
|
|
|
if resultStatus.ErrorCode != commonpb.ErrorCode_Success {
|
|
|
|
rollBackTasks := triggerTask.RollBack(scheduler.ctx)
|
|
|
|
log.Debug("scheduleLoop: start rollBack after triggerTask failed",
|
|
|
|
zap.Int64("triggerTaskID", triggerTask.ID()),
|
|
|
|
zap.Any("rollBackTasks", rollBackTasks))
|
|
|
|
err = rollBackInterTaskFn(triggerTask, childTasks, rollBackTasks)
|
|
|
|
if err != nil {
|
|
|
|
log.Error("scheduleLoop: rollBackInternalTask error",
|
|
|
|
zap.Int64("triggerTaskID", triggerTask.ID()),
|
|
|
|
zap.Error(err))
|
|
|
|
triggerTask.SetResultInfo(err)
|
|
|
|
} else {
|
|
|
|
processInternalTaskFn(rollBackTasks, triggerTask)
|
|
|
|
}
|
|
|
|
}
|
2021-08-02 22:39:25 +08:00
|
|
|
}
|
|
|
|
|
2021-10-11 09:54:37 +08:00
|
|
|
err = removeTaskFromKVFn(triggerTask)
|
2021-06-19 11:45:09 +08:00
|
|
|
if err != nil {
|
2021-10-11 09:54:37 +08:00
|
|
|
log.Error("scheduleLoop: error when remove trigger and internal tasks from etcd", zap.Int64("triggerTaskID", triggerTask.ID()), zap.Error(err))
|
|
|
|
triggerTask.SetResultInfo(err)
|
|
|
|
} else {
|
|
|
|
log.Debug("scheduleLoop: trigger task done and delete from etcd", zap.Int64("triggerTaskID", triggerTask.ID()))
|
|
|
|
}
|
|
|
|
|
|
|
|
resultStatus := triggerTask.GetResultInfo()
|
|
|
|
if resultStatus.ErrorCode != commonpb.ErrorCode_Success {
|
|
|
|
triggerTask.SetState(taskFailed)
|
|
|
|
if !alreadyNotify {
|
|
|
|
triggerTask.Notify(errors.New(resultStatus.Reason))
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
triggerTask.UpdateTaskProcess()
|
|
|
|
triggerTask.SetState(taskExpired)
|
|
|
|
if !alreadyNotify {
|
|
|
|
triggerTask.Notify(nil)
|
|
|
|
}
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
2021-06-15 12:41:40 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-11 09:54:37 +08:00
|
|
|
func (scheduler *TaskScheduler) waitActivateTaskDone(wg *sync.WaitGroup, t task, triggerTask task) {
|
2021-06-15 12:41:40 +08:00
|
|
|
defer wg.Done()
|
2021-10-11 09:54:37 +08:00
|
|
|
var err error
|
|
|
|
redoFunc1 := func() {
|
|
|
|
if !t.IsValid() || !t.IsRetryable() {
|
|
|
|
log.Debug("waitActivateTaskDone: reSchedule the activate task",
|
|
|
|
zap.Int64("taskID", t.ID()),
|
|
|
|
zap.Int64("triggerTaskID", triggerTask.ID()))
|
|
|
|
reScheduledTasks, err := t.Reschedule(scheduler.ctx)
|
|
|
|
if err != nil {
|
|
|
|
log.Error("waitActivateTaskDone: reschedule task error",
|
|
|
|
zap.Int64("taskID", t.ID()),
|
|
|
|
zap.Int64("triggerTaskID", triggerTask.ID()),
|
|
|
|
zap.Error(err))
|
|
|
|
triggerTask.SetResultInfo(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
removes := make([]string, 0)
|
|
|
|
taskKey := fmt.Sprintf("%s/%d", activeTaskPrefix, t.ID())
|
|
|
|
removes = append(removes, taskKey)
|
|
|
|
stateKey := fmt.Sprintf("%s/%d", taskInfoPrefix, t.ID())
|
|
|
|
removes = append(removes, stateKey)
|
|
|
|
|
|
|
|
saves := make(map[string]string)
|
|
|
|
for _, rt := range reScheduledTasks {
|
|
|
|
if rt != nil {
|
|
|
|
id, err := scheduler.taskIDAllocator()
|
|
|
|
if err != nil {
|
|
|
|
log.Error("waitActivateTaskDone: allocate id error",
|
|
|
|
zap.Int64("triggerTaskID", triggerTask.ID()),
|
|
|
|
zap.Error(err))
|
|
|
|
triggerTask.SetResultInfo(err)
|
|
|
|
return
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
rt.SetID(id)
|
|
|
|
log.Debug("waitActivateTaskDone: reScheduler set id", zap.Int64("id", rt.ID()))
|
|
|
|
taskKey := fmt.Sprintf("%s/%d", activeTaskPrefix, rt.ID())
|
|
|
|
blobs, err := rt.Marshal()
|
|
|
|
if err != nil {
|
|
|
|
log.Error("waitActivateTaskDone: error when marshal active task",
|
|
|
|
zap.Int64("triggerTaskID", triggerTask.ID()),
|
|
|
|
zap.Error(err))
|
|
|
|
triggerTask.SetResultInfo(err)
|
|
|
|
return
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
saves[taskKey] = string(blobs)
|
|
|
|
stateKey := fmt.Sprintf("%s/%d", taskInfoPrefix, rt.ID())
|
|
|
|
saves[stateKey] = strconv.Itoa(int(taskUndo))
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
//TODO::queryNode auto watch queryChannel, then update etcd use same id directly
|
|
|
|
err = scheduler.client.MultiSaveAndRemove(saves, removes)
|
|
|
|
if err != nil {
|
|
|
|
log.Error("waitActivateTaskDone: error when save and remove task from etcd", zap.Int64("triggerTaskID", triggerTask.ID()))
|
|
|
|
triggerTask.SetResultInfo(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
triggerTask.RemoveChildTaskByID(t.ID())
|
|
|
|
log.Debug("waitActivateTaskDone: delete failed active task and save reScheduled task to etcd",
|
|
|
|
zap.Int64("triggerTaskID", triggerTask.ID()),
|
|
|
|
zap.Int64("failed taskID", t.ID()),
|
|
|
|
zap.Any("reScheduled tasks", reScheduledTasks))
|
|
|
|
|
|
|
|
for _, rt := range reScheduledTasks {
|
|
|
|
if rt != nil {
|
|
|
|
triggerTask.AddChildTask(rt)
|
|
|
|
log.Debug("waitActivateTaskDone: add a reScheduled active task to activateChan", zap.Int64("taskID", rt.ID()))
|
|
|
|
scheduler.activateTaskChan <- rt
|
|
|
|
wg.Add(1)
|
|
|
|
go scheduler.waitActivateTaskDone(wg, rt, triggerTask)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//delete task from etcd
|
|
|
|
} else {
|
|
|
|
log.Debug("waitActivateTaskDone: retry the active task",
|
|
|
|
zap.Int64("taskID", t.ID()),
|
|
|
|
zap.Int64("triggerTaskID", triggerTask.ID()))
|
|
|
|
scheduler.activateTaskChan <- t
|
|
|
|
wg.Add(1)
|
|
|
|
go scheduler.waitActivateTaskDone(wg, t, triggerTask)
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
}
|
2021-06-19 11:45:09 +08:00
|
|
|
|
2021-10-11 09:54:37 +08:00
|
|
|
redoFunc2 := func(err error) {
|
|
|
|
if t.IsValid() {
|
|
|
|
if !t.IsRetryable() {
|
|
|
|
log.Error("waitActivateTaskDone: activate task failed after retry",
|
|
|
|
zap.Int64("taskID", t.ID()),
|
|
|
|
zap.Int64("triggerTaskID", triggerTask.ID()))
|
|
|
|
triggerTask.SetResultInfo(err)
|
|
|
|
return
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
log.Debug("waitActivateTaskDone: retry the active task",
|
|
|
|
zap.Int64("taskID", t.ID()),
|
|
|
|
zap.Int64("triggerTaskID", triggerTask.ID()))
|
|
|
|
scheduler.activateTaskChan <- t
|
|
|
|
wg.Add(1)
|
|
|
|
go scheduler.waitActivateTaskDone(wg, t, triggerTask)
|
2021-06-19 11:45:09 +08:00
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
}
|
|
|
|
err = t.WaitToFinish()
|
|
|
|
if err != nil {
|
|
|
|
log.Debug("waitActivateTaskDone: activate task return err",
|
|
|
|
zap.Int64("taskID", t.ID()),
|
|
|
|
zap.Int64("triggerTaskID", triggerTask.ID()),
|
|
|
|
zap.Error(err))
|
2021-06-19 11:45:09 +08:00
|
|
|
|
|
|
|
switch t.Type() {
|
|
|
|
case commonpb.MsgType_LoadSegments:
|
|
|
|
redoFunc1()
|
|
|
|
case commonpb.MsgType_WatchDmChannels:
|
|
|
|
redoFunc1()
|
|
|
|
case commonpb.MsgType_WatchQueryChannels:
|
2021-10-11 09:54:37 +08:00
|
|
|
redoFunc2(err)
|
2021-06-19 11:45:09 +08:00
|
|
|
case commonpb.MsgType_ReleaseSegments:
|
2021-10-11 09:54:37 +08:00
|
|
|
redoFunc2(err)
|
2021-06-19 11:45:09 +08:00
|
|
|
case commonpb.MsgType_ReleaseCollection:
|
2021-10-11 09:54:37 +08:00
|
|
|
redoFunc2(err)
|
2021-06-19 11:45:09 +08:00
|
|
|
case commonpb.MsgType_ReleasePartitions:
|
2021-10-11 09:54:37 +08:00
|
|
|
redoFunc2(err)
|
2021-06-19 11:45:09 +08:00
|
|
|
default:
|
|
|
|
//TODO:: case commonpb.MsgType_RemoveDmChannels:
|
|
|
|
}
|
|
|
|
} else {
|
2021-10-11 09:54:37 +08:00
|
|
|
log.Debug("waitActivateTaskDone: one activate task done",
|
|
|
|
zap.Int64("taskID", t.ID()),
|
|
|
|
zap.Int64("triggerTaskID", triggerTask.ID()))
|
2021-06-15 12:41:40 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-19 11:45:09 +08:00
|
|
|
func (scheduler *TaskScheduler) processActivateTaskLoop() {
|
|
|
|
defer scheduler.wg.Done()
|
2021-06-15 12:41:40 +08:00
|
|
|
for {
|
|
|
|
select {
|
2021-10-11 09:54:37 +08:00
|
|
|
case <-scheduler.stopActivateTaskLoopChan:
|
|
|
|
log.Debug("processActivateTaskLoop, ctx done")
|
2021-06-15 12:41:40 +08:00
|
|
|
return
|
2021-10-11 09:54:37 +08:00
|
|
|
|
2021-06-15 12:41:40 +08:00
|
|
|
case t := <-scheduler.activateTaskChan:
|
|
|
|
if t == nil {
|
2021-06-19 11:45:09 +08:00
|
|
|
log.Error("processActivateTaskLoop: pop a nil active task", zap.Int64("taskID", t.ID()))
|
|
|
|
continue
|
|
|
|
}
|
2021-10-11 09:54:37 +08:00
|
|
|
|
2021-06-19 11:45:09 +08:00
|
|
|
log.Debug("processActivateTaskLoop: pop a active task from activateChan", zap.Int64("taskID", t.ID()))
|
|
|
|
go func() {
|
|
|
|
err := scheduler.processTask(t)
|
|
|
|
t.Notify(err)
|
|
|
|
}()
|
2021-06-15 12:41:40 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-04-15 15:15:46 +08:00
|
|
|
|
2021-06-15 12:41:40 +08:00
|
|
|
func (scheduler *TaskScheduler) Start() error {
|
2021-06-19 11:45:09 +08:00
|
|
|
scheduler.wg.Add(2)
|
2021-06-15 12:41:40 +08:00
|
|
|
go scheduler.scheduleLoop()
|
2021-06-19 11:45:09 +08:00
|
|
|
go scheduler.processActivateTaskLoop()
|
2021-04-15 15:15:46 +08:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-06-15 12:41:40 +08:00
|
|
|
func (scheduler *TaskScheduler) Close() {
|
|
|
|
scheduler.cancel()
|
|
|
|
scheduler.wg.Wait()
|
2021-04-15 15:15:46 +08:00
|
|
|
}
|