github.com/pingcap/tiflow@v0.0.0-20240520035814-5bf52d54e205/pkg/p2p/client.go (about)

     1  // Copyright 2021 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 p2p
    15  
    16  import (
    17  	"context"
    18  	"sync/atomic"
    19  	"time"
    20  
    21  	"github.com/pingcap/tiflow/pkg/errors"
    22  	"github.com/pingcap/tiflow/pkg/security"
    23  )
    24  
    25  var _ MessageClient = &grpcMessageClient{}
    26  
    27  // MessageClient is an interface for sending messages to a remote peer.
    28  type MessageClient interface {
    29  	// Run should be executed in a dedicated goroutine and it would block unless an irrecoverable error has been encountered.
    30  	Run(ctx context.Context, network string, addr string, receiverID NodeID, credential *security.Credential) (ret error)
    31  
    32  	// SendMessage sends a message of a given topic. It would block if the inner channel is congested.
    33  	SendMessage(ctx context.Context, topic Topic, value interface{}) (seq Seq, ret error)
    34  
    35  	// TrySendMessage tries to send a message of a given topic. It will return an error if the inner channel is congested.
    36  	TrySendMessage(ctx context.Context, topic Topic, value interface{}) (seq Seq, ret error)
    37  
    38  	// CurrentAck is used to query the latest sequence number for a topic that is acknowledged by the server.
    39  	// Note: currently only used for test.
    40  	CurrentAck(topic Topic) (Seq, bool)
    41  }
    42  
    43  // MessageClientConfig is used to configure MessageClient
    44  type MessageClientConfig struct {
    45  	// The size of the sending channel used to buffer
    46  	// messages before they go to gRPC.
    47  	SendChannelSize int
    48  	// The maximum duration for which messages wait to be batched.
    49  	BatchSendInterval time.Duration
    50  	// The maximum size in bytes of a batch.
    51  	MaxBatchBytes int
    52  	// The maximum number of messages in a batch.
    53  	MaxBatchCount int
    54  	// The limit of the rate at which the connection to the server is retried.
    55  	RetryRateLimitPerSecond float64
    56  	// The dial timeout for the gRPC client
    57  	DialTimeout time.Duration
    58  	// The advertised address of this node. Used for logging and monitoring purposes.
    59  	AdvertisedAddr string
    60  	// The version of the client for compatibility check.
    61  	// It should be in semver format. Empty string means no check.
    62  	ClientVersion string
    63  	// MaxRecvMsgSize is the maximum message size in bytes TiCDC can receive.
    64  	MaxRecvMsgSize int
    65  }
    66  
    67  type localMessageClient struct {
    68  	ctx     context.Context
    69  	idx     atomic.Int64
    70  	localCh chan RawMessageEntry
    71  	// config is read only
    72  	config *MessageClientConfig
    73  }
    74  
    75  func newLocalMessageClient(ctx context.Context, config *MessageClientConfig) MessageClient {
    76  	return &localMessageClient{
    77  		ctx:     ctx,
    78  		idx:     atomic.Int64{},
    79  		localCh: make(chan RawMessageEntry, config.SendChannelSize),
    80  		config:  config,
    81  	}
    82  }
    83  
    84  func (c *localMessageClient) Run(
    85  	ctx context.Context, network string, addr string, receiverID NodeID, credential *security.Credential,
    86  ) error {
    87  	return nil
    88  }
    89  
    90  func (c *localMessageClient) SendMessage(ctx context.Context, topic Topic, value interface{}) (Seq, error) {
    91  	select {
    92  	case <-ctx.Done():
    93  		return 0, ctx.Err()
    94  	case <-c.ctx.Done():
    95  		return 0, errors.WrapError(errors.ErrPeerMessageClientClosed, c.ctx.Err())
    96  	case c.localCh <- RawMessageEntry{topic, value}:
    97  		return c.idx.Add(1), nil
    98  	}
    99  }
   100  
   101  func (c *localMessageClient) TrySendMessage(ctx context.Context, topic Topic, value interface{}) (Seq, error) {
   102  	select {
   103  	case <-ctx.Done():
   104  		return 0, ctx.Err()
   105  	case c.localCh <- RawMessageEntry{topic, value}:
   106  		return c.idx.Add(1), nil
   107  	default:
   108  		return 0, errors.ErrPeerMessageSendTryAgain.GenWithStackByArgs()
   109  	}
   110  }
   111  
   112  func (c *localMessageClient) CurrentAck(topic Topic) (Seq, bool) {
   113  	return c.idx.Load(), false
   114  }