github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/dm/pkg/ha/ops.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 package ha 15 16 import ( 17 "github.com/pingcap/tiflow/dm/config" 18 "github.com/pingcap/tiflow/dm/pkg/etcdutil" 19 "go.etcd.io/etcd/api/v3/mvccpb" 20 clientv3 "go.etcd.io/etcd/client/v3" 21 ) 22 23 // PutRelayStageSourceBound puts the following data in one txn. 24 // - relay stage. 25 // - source bound relationship. 26 func PutRelayStageSourceBound(cli *clientv3.Client, stage Stage, bound SourceBound) (int64, error) { 27 ops1, err := putRelayStageOp(stage) 28 if err != nil { 29 return 0, err 30 } 31 op2, err := putSourceBoundOp(bound) 32 if err != nil { 33 return 0, err 34 } 35 ops := make([]clientv3.Op, 0, len(ops1)+len(op2)) 36 ops = append(ops, ops1...) 37 ops = append(ops, op2...) 38 _, rev, err := etcdutil.DoTxnWithRepeatable(cli, etcdutil.ThenOpFunc(ops...)) 39 return rev, err 40 } 41 42 // PutRelayStageRelayConfigSourceBound puts the following data in one txn. 43 // - relay stage. 44 // - relay config for a worker 45 // - source bound relationship. 46 func PutRelayStageRelayConfigSourceBound(cli *clientv3.Client, stage Stage, bound SourceBound) (int64, error) { 47 ops1, err := putRelayStageOp(stage) 48 if err != nil { 49 return 0, err 50 } 51 op2, err := putSourceBoundOp(bound) 52 if err != nil { 53 return 0, err 54 } 55 op3 := putRelayConfigOp(bound.Worker, bound.Source) 56 ops := make([]clientv3.Op, 0, len(ops1)+len(op2)+1) 57 ops = append(ops, ops1...) 58 ops = append(ops, op2...) 59 ops = append(ops, op3) 60 _, rev, err := etcdutil.DoTxnWithRepeatable(cli, etcdutil.ThenOpFunc(ops...)) 61 return rev, err 62 } 63 64 // DeleteSourceCfgRelayStageSourceBound deletes the following data in one txn. 65 // - upstream source config. 66 // - relay stage. 67 // - source bound relationship. 68 func DeleteSourceCfgRelayStageSourceBound(cli *clientv3.Client, source, worker string) (int64, error) { 69 sourceCfgOp := deleteSourceCfgOp(source) 70 relayStageOp := deleteRelayStageOp(source) 71 sourceBoundOp := deleteSourceBoundOp(worker) 72 lastBoundOp := deleteLastSourceBoundOp(worker) 73 ops := make([]clientv3.Op, 0, 3+len(sourceBoundOp)) 74 ops = append(ops, sourceCfgOp) 75 ops = append(ops, relayStageOp) 76 ops = append(ops, sourceBoundOp...) 77 ops = append(ops, lastBoundOp) 78 79 _, rev, err := etcdutil.DoTxnWithRepeatable(cli, etcdutil.ThenOpFunc(ops...)) 80 return rev, err 81 } 82 83 // PutSubTaskCfgStage puts the following data in one txn. 84 // - subtask config. 85 // - subtask stage. 86 // NOTE: golang can't use two `...` in the func, so use `[]` instead. 87 func PutSubTaskCfgStage(cli *clientv3.Client, cfgs []config.SubTaskConfig, stages []Stage, validatorStages []Stage) (int64, error) { 88 return operateSubtask(cli, mvccpb.PUT, cfgs, stages, validatorStages) 89 } 90 91 // DeleteSubTaskCfgStage deletes the following data in one txn. 92 // - subtask config. 93 // - subtask stage. 94 // NOTE: golang can't use two `...` in the func, so use `[]` instead. 95 func DeleteSubTaskCfgStage(cli *clientv3.Client, cfgs []config.SubTaskConfig, stages []Stage, validatorStages []Stage) (int64, error) { 96 return operateSubtask(cli, mvccpb.DELETE, cfgs, stages, validatorStages) 97 } 98 99 // operateSubtask puts/deletes KVs for the subtask in one txn. 100 func operateSubtask(cli *clientv3.Client, evType mvccpb.Event_EventType, cfgs []config.SubTaskConfig, stages []Stage, 101 validatorStages []Stage, 102 ) (int64, error) { 103 var ( 104 ops1 []clientv3.Op 105 ops2 []clientv3.Op 106 validatorOps []clientv3.Op 107 err error 108 ) 109 switch evType { 110 case mvccpb.PUT: 111 ops1, err = putSubTaskCfgOp(cfgs...) 112 if err != nil { 113 return 0, err 114 } 115 ops2, err = putSubTaskStageOp(stages...) 116 if err != nil { 117 return 0, err 118 } 119 validatorOps, err = putValidatorStageOps(validatorStages...) 120 if err != nil { 121 return 0, err 122 } 123 case mvccpb.DELETE: 124 ops1 = deleteSubTaskCfgOp(cfgs...) 125 ops2 = deleteSubTaskStageOp(stages...) 126 validatorOps = deleteValidatorStageOps(validatorStages...) 127 } 128 129 ops := make([]clientv3.Op, 0, 2*len(cfgs)+len(stages)) 130 ops = append(ops, ops1...) 131 ops = append(ops, ops2...) 132 ops = append(ops, validatorOps...) 133 _, rev, err := etcdutil.DoTxnWithRepeatable(cli, etcdutil.ThenOpFunc(ops...)) 134 return rev, err 135 }