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  }