github.com/matrixorigin/matrixone@v1.2.0/pkg/hakeeper/operator/operator.go (about) 1 // Copyright 2020 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 // Portions of this file are additionally subject to the following 15 // copyright. 16 // 17 // Copyright (C) 2021 Matrix Origin. 18 // 19 // Modified the behavior of the operator. 20 21 package operator 22 23 import ( 24 "time" 25 26 pb "github.com/matrixorigin/matrixone/pkg/pb/logservice" 27 ) 28 29 const ( 30 ExpireTime = 15 * time.Second 31 NoopEpoch uint64 = 0 32 NoopShardID uint64 = 0 33 ) 34 35 // Operator contains execution steps generated by scheduler. 36 type Operator struct { 37 brief string 38 39 shardID uint64 40 epoch uint64 41 42 steps []OpStep 43 currentStep int32 44 45 status OpStatusTracker 46 } 47 48 // NewOperator creates a new operator. 49 func NewOperator(brief string, shardID uint64, epoch uint64, steps ...OpStep) *Operator { 50 return &Operator{ 51 brief: brief, 52 shardID: shardID, 53 epoch: epoch, 54 55 steps: steps, 56 status: NewOpStatusTracker(), 57 } 58 } 59 60 // ShardID returns shard ID. 61 func (o *Operator) ShardID() uint64 { 62 return o.shardID 63 } 64 65 // OpSteps returns operator steps. 66 func (o *Operator) OpSteps() []OpStep { 67 return o.steps 68 } 69 70 // Status returns operator status. 71 func (o *Operator) Status() OpStatus { 72 return o.status.Status() 73 } 74 75 // SetStatus only used for tests. 76 func (o *Operator) SetStatus(status OpStatus) { 77 o.status.setStatus(status) 78 } 79 80 // Cancel marks the operator canceled. 81 func (o *Operator) Cancel() bool { 82 return o.status.To(CANCELED) 83 } 84 85 // HasStarted returns whether operator has started. 86 func (o *Operator) HasStarted() bool { 87 return !o.GetStartTime().IsZero() 88 } 89 90 // GetStartTime gets the start time of operator. 91 func (o *Operator) GetStartTime() time.Time { 92 return o.status.ReachTimeOf(STARTED) 93 } 94 95 // IsEnd checks if the operator is at and end status. 96 func (o *Operator) IsEnd() bool { 97 return o.status.IsEnd() 98 } 99 100 // CheckSuccess checks if all steps are finished, and update the status. 101 func (o *Operator) CheckSuccess() bool { 102 if o.currentStep >= int32(len(o.steps)) { 103 return o.status.To(SUCCESS) || o.Status() == SUCCESS 104 } 105 return false 106 } 107 108 // CheckExpired checks if the operator is timeout, and update the status. 109 func (o *Operator) CheckExpired() bool { 110 if o.CheckSuccess() { 111 return false 112 } 113 return o.status.CheckExpired(ExpireTime) 114 } 115 116 func (o *Operator) Check( 117 logState pb.LogState, tnState pb.TNState, cnState pb.CNState, proxyState pb.ProxyState, 118 ) OpStep { 119 if o.IsEnd() { 120 return nil 121 } 122 // CheckExpired will call CheckSuccess first 123 defer func() { _ = o.CheckExpired() }() 124 for step := o.currentStep; int(step) < len(o.steps); step++ { 125 if o.steps[int(step)].IsFinish(ClusterState{ 126 LogState: logState, 127 TNState: tnState, 128 CNState: cnState, 129 ProxyState: proxyState, 130 }) { 131 o.currentStep = step + 1 132 } else { 133 return o.steps[int(step)] 134 } 135 } 136 return nil 137 }