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  }