github.com/jtzjtz/kit@v1.0.2/conn/rpc_pool/rpc_pool.go (about)

     1  package rpc_pool
     2  
     3  import (
     4  	"errors"
     5  	"github.com/jtzjtz/kit/conn/grpc_pool"
     6  	"google.golang.org/grpc"
     7  	"log"
     8  	"sync"
     9  	"time"
    10  )
    11  
    12  //rpc 连接池
    13  type RpcPool struct {
    14  	rpcPool    *grpc_pool.GRPCPool
    15  	rpcOptions *grpc_pool.Options
    16  	mu         sync.Mutex
    17  	getMu      sync.Mutex
    18  }
    19  
    20  //取rpc连接 (支持连接池重连)
    21  func (current RpcPool) Get() (*grpc.ClientConn, error) {
    22  	current.getMu.Lock()
    23  	defer current.getMu.Unlock()
    24  	if current.rpcPool == nil {
    25  		err := current.reConnect()
    26  		if err != nil {
    27  			return nil, err
    28  		}
    29  	}
    30  	con, errRpc := current.rpcPool.Get()
    31  	if errRpc != nil { //之前连接池有值,现在连接不上 重连
    32  		errCon := current.reConnect()
    33  		if errCon != nil {
    34  			return nil, errors.New("之前连接池有值,现在连接不上 重连失败 原因:" + errCon.Error())
    35  		} else if current.rpcPool != nil { //重连成功
    36  			return current.rpcPool.Get()
    37  		} else {
    38  			return nil, errors.New("之前连接池有值,现在连接不上 重连后 连接池为空")
    39  		}
    40  
    41  	} else {
    42  		return con, nil
    43  	}
    44  
    45  }
    46  
    47  //释放rpc连接  建议用此方法 名字好,容易理解
    48  func (current RpcPool) Dispose(rpcConnection *grpc.ClientConn) error {
    49  	return current.Put(rpcConnection)
    50  }
    51  
    52  //释放rpc连接
    53  func (current RpcPool) Put(rpcConnection *grpc.ClientConn) error {
    54  	if current.rpcPool != nil {
    55  		return current.rpcPool.Put(rpcConnection)
    56  	}
    57  	return errors.New("不存在的连接池不能放回连接")
    58  }
    59  
    60  //重新连接
    61  func (current RpcPool) reConnect() error {
    62  	if current.rpcOptions == nil {
    63  		return errors.New("rpc 初始值为空,请重启应用赋值")
    64  
    65  	}
    66  	_, err := current.Connect(current.rpcOptions)
    67  	time.Sleep(time.Second * 1) //初始化连接池为异步,等待1s
    68  	if current.rpcPool == nil { //如果还为空 返回错误
    69  		if err != nil {
    70  			return errors.New(" GRPC 连接重连失败,请稍后重试 原因:" + err.Error())
    71  		}
    72  		return errors.New(" GRPC 连接重连失败,请稍后重试")
    73  	}
    74  	return err
    75  
    76  }
    77  
    78  //初始化连接池
    79  func (current RpcPool) Connect(rpcOptions *grpc_pool.Options) (RpcPool, error) {
    80  	var err error
    81  	current.rpcOptions = rpcOptions
    82  	if current.rpcPool == nil {
    83  		current.mu.Lock()
    84  		if current.rpcPool == nil {
    85  			current.rpcPool, err = grpc_pool.NewGRPCPool(rpcOptions, grpc.WithInsecure(), grpc.WithBlock())
    86  		}
    87  		current.mu.Unlock()
    88  	}
    89  
    90  	if err != nil {
    91  		if len(rpcOptions.InitTargets) > 0 {
    92  			log.Printf("getGrpcPool err:%#v url:%#v\n", err, rpcOptions.InitTargets[0])
    93  		} else {
    94  			log.Printf("getGrpcPool err:%#v url: null", err)
    95  		}
    96  	}
    97  	return current, err
    98  
    99  }