github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/engine/framework/model/worker.go (about) 1 // Copyright 2022 PingCAP, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package model 15 16 import ( 17 "encoding/json" 18 19 ormModel "github.com/pingcap/tiflow/engine/pkg/orm/model" 20 "github.com/pingcap/tiflow/engine/pkg/tenant" 21 "github.com/pingcap/tiflow/pkg/errors" 22 ) 23 24 // WorkerState represents worker running status in master worker framework 25 // TODO: add fsm of WorkerState 26 type WorkerState int8 27 28 // Among these statuses, only WorkerStateCreated is used by the framework 29 // for now. The rest are for the business logic to use. 30 // TODO think about whether to manage the transition of the statuses. 31 // TODO: need a FSM graph 32 // NOTICE: DO NOT CHANGE the previous status code 33 // Modify the WorkerStatus.State comment IF you add some new status code 34 const ( 35 WorkerStateNormal = WorkerState(1) 36 WorkerStateCreated = WorkerState(2) 37 WorkerStateInit = WorkerState(3) 38 WorkerStateError = WorkerState(4) 39 WorkerStateFinished = WorkerState(5) 40 WorkerStateStopped = WorkerState(6) 41 // extend the status code here 42 ) 43 44 // WorkerUpdateColumns is used in gorm update. 45 // TODO: using reflect to generate it more generally 46 // related to some implement of gorm 47 var WorkerUpdateColumns = []string{ 48 "updated_at", 49 "project_id", 50 "job_id", 51 "id", 52 "type", 53 "state", 54 "epoch", 55 "error_message", 56 "extend_bytes", 57 } 58 59 // WorkerStatus records worker information, including master id, worker id, 60 // worker type, project id(tenant), worker status(used in master worker framework), 61 // error message and ext bytes(passed from business logic) in metastore. 62 type WorkerStatus struct { 63 ormModel.Model 64 ProjectID tenant.ProjectID `json:"project-id" gorm:"column:project_id;type:varchar(128) not null"` 65 JobID MasterID `json:"job-id" gorm:"column:job_id;type:varchar(128) not null;uniqueIndex:uidx_wid,priority:1;index:idx_wst,priority:1"` 66 ID WorkerID `json:"id" gorm:"column:id;type:varchar(128) not null;uniqueIndex:uidx_wid,priority:2"` 67 Type WorkerType `json:"type" gorm:"column:type;type:smallint not null;comment:JobManager(1),CvsJobMaster(2),FakeJobMaster(3),DMJobMaster(4),CDCJobMaster(5),CvsTask(6),FakeTask(7),DMTask(8),CDCTask(9),WorkerDMDump(10),WorkerDMLoad(11),WorkerDMSync(12)"` 68 State WorkerState `json:"state" gorm:"column:state;type:tinyint not null;index:idx_wst,priority:2;comment:Normal(1),Created(2),Init(3),Error(4),Finished(5),Stopped(6)"` 69 Epoch Epoch `json:"epoch" gorm:"column:epoch;type:bigint not null"` 70 ErrorMsg string `json:"error-message" gorm:"column:error_message;type:text"` 71 72 // ExtBytes carries the serialized form of the Ext field, which is used in 73 // business logic only. 74 // Business logic can parse the raw bytes and decode into business Go object 75 ExtBytes []byte `json:"extend-bytes" gorm:"column:extend_bytes;type:blob"` 76 } 77 78 // HasSignificantChange indicates whether `s` has significant changes worth persisting. 79 func (s WorkerStatus) HasSignificantChange(other *WorkerStatus) bool { 80 return s.State != other.State || s.ErrorMsg != other.ErrorMsg 81 } 82 83 // InTerminateState returns whether worker is in a terminate state, including 84 // finished, stopped, error. 85 func (s *WorkerStatus) InTerminateState() bool { 86 switch s.State { 87 case WorkerStateFinished, WorkerStateStopped, WorkerStateError: 88 return true 89 default: 90 return false 91 } 92 } 93 94 // Marshal returns the JSON encoding of WorkerStatus. 95 func (s *WorkerStatus) Marshal() ([]byte, error) { 96 return json.Marshal(s) 97 } 98 99 // Unmarshal parses the JSON-encoded data and stores the result into a WorkerStatus 100 func (s *WorkerStatus) Unmarshal(bytes []byte) error { 101 if err := json.Unmarshal(bytes, s); err != nil { 102 return errors.Trace(err) 103 } 104 return nil 105 } 106 107 // Map is used for update the orm model 108 func (s *WorkerStatus) Map() map[string]interface{} { 109 return map[string]interface{}{ 110 "project_id": s.ProjectID, 111 "job_id": s.JobID, 112 "id": s.ID, 113 "type": s.Type, 114 "state": s.State, 115 "epoch": s.Epoch, 116 "error_message": s.ErrorMsg, 117 "extend_bytes": s.ExtBytes, 118 } 119 }