Files
tidb/pkg/disttask/framework/proto/task.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("{}")
)