github.com/pingcap/ticdc@v0.0.0-20220526033649-485a10ef2652/cdc/processor/pipeline/puller.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 pipeline 15 16 import ( 17 "context" 18 19 "github.com/pingcap/errors" 20 "github.com/pingcap/ticdc/cdc/model" 21 "github.com/pingcap/ticdc/cdc/puller" 22 cdcContext "github.com/pingcap/ticdc/pkg/context" 23 "github.com/pingcap/ticdc/pkg/pipeline" 24 "github.com/pingcap/ticdc/pkg/regionspan" 25 "github.com/pingcap/ticdc/pkg/util" 26 "github.com/pingcap/tidb/store/tikv/oracle" 27 "golang.org/x/sync/errgroup" 28 ) 29 30 type pullerNode struct { 31 tableName string // quoted schema and table, used in metircs only 32 33 tableID model.TableID 34 replicaInfo *model.TableReplicaInfo 35 cancel context.CancelFunc 36 wg errgroup.Group 37 } 38 39 func newPullerNode( 40 tableID model.TableID, replicaInfo *model.TableReplicaInfo, tableName string) pipeline.Node { 41 return &pullerNode{ 42 tableID: tableID, 43 replicaInfo: replicaInfo, 44 tableName: tableName, 45 } 46 } 47 48 func (n *pullerNode) tableSpan(ctx cdcContext.Context) []regionspan.Span { 49 // start table puller 50 config := ctx.ChangefeedVars().Info.Config 51 spans := make([]regionspan.Span, 0, 4) 52 spans = append(spans, regionspan.GetTableSpan(n.tableID)) 53 54 if config.Cyclic.IsEnabled() && n.replicaInfo.MarkTableID != 0 { 55 spans = append(spans, regionspan.GetTableSpan(n.replicaInfo.MarkTableID)) 56 } 57 return spans 58 } 59 60 func (n *pullerNode) Init(ctx pipeline.NodeContext) error { 61 metricTableResolvedTsGauge := tableResolvedTsGauge.WithLabelValues(ctx.ChangefeedVars().ID, ctx.GlobalVars().CaptureInfo.AdvertiseAddr, n.tableName) 62 ctxC, cancel := context.WithCancel(ctx) 63 ctxC = util.PutTableInfoInCtx(ctxC, n.tableID, n.tableName) 64 ctxC = util.PutCaptureAddrInCtx(ctxC, ctx.GlobalVars().CaptureInfo.AdvertiseAddr) 65 ctxC = util.PutChangefeedIDInCtx(ctxC, ctx.ChangefeedVars().ID) 66 // NOTICE: always pull the old value internally 67 // See also: TODO(hi-rustin): add issue link here. 68 plr := puller.NewPuller(ctxC, ctx.GlobalVars().PDClient, ctx.GlobalVars().GrpcPool, ctx.GlobalVars().KVStorage, 69 n.replicaInfo.StartTs, n.tableSpan(ctx), true) 70 n.wg.Go(func() error { 71 ctx.Throw(errors.Trace(plr.Run(ctxC))) 72 return nil 73 }) 74 n.wg.Go(func() error { 75 for { 76 select { 77 case <-ctxC.Done(): 78 return nil 79 case rawKV := <-plr.Output(): 80 if rawKV == nil { 81 continue 82 } 83 if rawKV.OpType == model.OpTypeResolved { 84 metricTableResolvedTsGauge.Set(float64(oracle.ExtractPhysical(rawKV.CRTs))) 85 } 86 pEvent := model.NewPolymorphicEvent(rawKV) 87 ctx.SendToNextNode(pipeline.PolymorphicEventMessage(pEvent)) 88 } 89 } 90 }) 91 n.cancel = cancel 92 return nil 93 } 94 95 // Receive receives the message from the previous node 96 func (n *pullerNode) Receive(ctx pipeline.NodeContext) error { 97 // just forward any messages to the next node 98 ctx.SendToNextNode(ctx.Message()) 99 return nil 100 } 101 102 func (n *pullerNode) Destroy(ctx pipeline.NodeContext) error { 103 tableResolvedTsGauge.DeleteLabelValues(ctx.ChangefeedVars().ID, ctx.GlobalVars().CaptureInfo.AdvertiseAddr, n.tableName) 104 n.cancel() 105 return n.wg.Wait() 106 }