160 lines
5.3 KiB
Go
160 lines
5.3 KiB
Go
// Copyright 2023 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,
|
|
// 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 proto
|
|
|
|
import (
|
|
"time"
|
|
)
|
|
|
|
// task state machine
|
|
//
|
|
// Note: if a task fails during running, it will end with `reverted` state.
|
|
// The `failed` state is used to mean the framework cannot run the task, such as
|
|
// invalid task type, scheduler init error(fatal), etc.
|
|
//
|
|
// ┌────────┐
|
|
// ┌───────────│resuming│◄────────┐
|
|
// │ └────────┘ │
|
|
// ┌──────┐ │ ┌───────┐ ┌──┴───┐
|
|
// │failed│ │ ┌────────►│pausing├──────►│paused│
|
|
// └──────┘ │ │ └───────┘ └──────┘
|
|
// ▲ ▼ │
|
|
// ┌──┴────┐ ┌───┴───┐ ┌────────┐
|
|
// │pending├────►│running├────►│succeed │
|
|
// └──┬────┘ └──┬┬───┘ └────────┘
|
|
// │ ││ ┌─────────┐ ┌────────┐
|
|
// │ │└────────►│reverting├────►│reverted│
|
|
// │ ▼ └─────────┘ └────────┘
|
|
// │ ┌──────────┐ ▲
|
|
// └─────────►│cancelling├────┘
|
|
// └──────────┘
|
|
const (
|
|
TaskStatePending TaskState = "pending"
|
|
TaskStateRunning TaskState = "running"
|
|
TaskStateSucceed TaskState = "succeed"
|
|
TaskStateFailed TaskState = "failed"
|
|
TaskStateReverting TaskState = "reverting"
|
|
TaskStateReverted TaskState = "reverted"
|
|
TaskStateCancelling TaskState = "cancelling"
|
|
TaskStatePausing TaskState = "pausing"
|
|
TaskStatePaused TaskState = "paused"
|
|
TaskStateResuming TaskState = "resuming"
|
|
)
|
|
|
|
type (
|
|
// TaskState is the state of task.
|
|
TaskState string
|
|
// TaskType is the type of task.
|
|
TaskType string
|
|
)
|
|
|
|
func (t TaskType) String() string {
|
|
return string(t)
|
|
}
|
|
|
|
func (s TaskState) String() string {
|
|
return string(s)
|
|
}
|
|
|
|
const (
|
|
// TaskIDLabelName is the label name of task id.
|
|
TaskIDLabelName = "task_id"
|
|
// NormalPriority represents the normal priority of task.
|
|
NormalPriority = 512
|
|
)
|
|
|
|
// MaxConcurrentTask is the max concurrency of task.
|
|
// TODO: remove this limit later.
|
|
var MaxConcurrentTask = 16
|
|
|
|
// TaskBase contains the basic information of a task.
|
|
// we define this to avoid load task meta which might be very large into memory.
|
|
type TaskBase struct {
|
|
ID int64
|
|
Key string
|
|
Type TaskType
|
|
State TaskState
|
|
Step Step
|
|
// Priority is the priority of task, the smaller value means the higher priority.
|
|
// valid range is [1, 1024], default is NormalPriority.
|
|
Priority int
|
|
// Concurrency controls the max resource usage of the task, i.e. the max number
|
|
// of slots the task can use on each node.
|
|
Concurrency int
|
|
CreateTime time.Time
|
|
}
|
|
|
|
// IsDone checks if the task is done.
|
|
func (t *TaskBase) IsDone() bool {
|
|
return t.State == TaskStateSucceed || t.State == TaskStateReverted ||
|
|
t.State == TaskStateFailed
|
|
}
|
|
|
|
// CompareTask a wrapper of Compare.
|
|
func (t *TaskBase) CompareTask(other *Task) int {
|
|
return t.Compare(&other.TaskBase)
|
|
}
|
|
|
|
// Compare compares two tasks by task rank.
|
|
// returns < 0 represents rank of t is higher than 'other'.
|
|
func (t *TaskBase) Compare(other *TaskBase) int {
|
|
if t.Priority != other.Priority {
|
|
return t.Priority - other.Priority
|
|
}
|
|
if t.CreateTime != other.CreateTime {
|
|
if t.CreateTime.Before(other.CreateTime) {
|
|
return -1
|
|
}
|
|
return 1
|
|
}
|
|
return int(t.ID - other.ID)
|
|
}
|
|
|
|
// Task represents the task of distributed framework.
|
|
// A task is abstracted as multiple steps that runs in sequence, each step contains
|
|
// multiple sub-tasks that runs in parallel, such as:
|
|
//
|
|
// task
|
|
// ├── step1
|
|
// │ ├── subtask1
|
|
// │ ├── subtask2
|
|
// │ └── subtask3
|
|
// └── step2
|
|
// ├── subtask1
|
|
// ├── subtask2
|
|
// └── subtask3
|
|
//
|
|
// tasks are run in the order of rank, and the rank is defined by:
|
|
//
|
|
// priority asc, create_time asc, id asc.
|
|
type Task struct {
|
|
TaskBase
|
|
// SchedulerID is not used now.
|
|
SchedulerID string
|
|
StartTime time.Time
|
|
StateUpdateTime time.Time
|
|
// Meta is the metadata of task, it's read-only in most cases, but it can be
|
|
// changed in below case, and framework will update the task meta in the storage.
|
|
// - task switches to next step in Scheduler.OnNextSubtasksBatch
|
|
// - on task cleanup, we might do some redaction on the meta.
|
|
Meta []byte
|
|
Error error
|
|
}
|
|
|
|
var (
|
|
// EmptyMeta is the empty meta of task/subtask.
|
|
EmptyMeta = []byte("{}")
|
|
)
|