dubbo.apache.org/dubbo-go/v3@v3.1.1/protocol/grpc/grpc_protocol.go (about)

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one or more
     3   * contributor license agreements.  See the NOTICE file distributed with
     4   * this work for additional information regarding copyright ownership.
     5   * The ASF licenses this file to You under the Apache License, Version 2.0
     6   * (the "License"); you may not use this file except in compliance with
     7   * the License.  You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  
    18  package grpc
    19  
    20  import (
    21  	"sync"
    22  )
    23  
    24  import (
    25  	"github.com/dubbogo/gost/log/logger"
    26  )
    27  
    28  import (
    29  	"dubbo.apache.org/dubbo-go/v3/common"
    30  	"dubbo.apache.org/dubbo-go/v3/common/extension"
    31  	"dubbo.apache.org/dubbo-go/v3/protocol"
    32  )
    33  
    34  const (
    35  	// GRPC module name
    36  	GRPC = "grpc"
    37  )
    38  
    39  func init() {
    40  	extension.SetProtocol(GRPC, GetProtocol)
    41  }
    42  
    43  var grpcProtocol *GrpcProtocol
    44  
    45  // GrpcProtocol is gRPC protocol
    46  type GrpcProtocol struct {
    47  	protocol.BaseProtocol
    48  	serverMap  map[string]*Server
    49  	serverLock sync.Mutex
    50  }
    51  
    52  // NewGRPCProtocol creates new gRPC protocol
    53  func NewGRPCProtocol() *GrpcProtocol {
    54  	return &GrpcProtocol{
    55  		BaseProtocol: protocol.NewBaseProtocol(),
    56  		serverMap:    make(map[string]*Server),
    57  	}
    58  }
    59  
    60  // Export gRPC service for remote invocation
    61  func (gp *GrpcProtocol) Export(invoker protocol.Invoker) protocol.Exporter {
    62  	url := invoker.GetURL()
    63  	serviceKey := url.ServiceKey()
    64  	exporter := NewGrpcExporter(serviceKey, invoker, gp.ExporterMap())
    65  	gp.SetExporterMap(serviceKey, exporter)
    66  	logger.Infof("[GRPC Protocol] Export service: %s", url.String())
    67  	gp.openServer(url)
    68  	return exporter
    69  }
    70  
    71  func (gp *GrpcProtocol) openServer(url *common.URL) {
    72  	gp.serverLock.Lock()
    73  	defer gp.serverLock.Unlock()
    74  
    75  	if _, ok := gp.serverMap[url.Location]; ok {
    76  		return
    77  	}
    78  
    79  	if _, ok := gp.ExporterMap().Load(url.ServiceKey()); !ok {
    80  		panic("[GrpcProtocol]" + url.Key() + "is not existing")
    81  	}
    82  
    83  	srv := NewServer()
    84  	gp.serverMap[url.Location] = srv
    85  	srv.Start(url)
    86  }
    87  
    88  // Refer a remote gRPC service
    89  func (gp *GrpcProtocol) Refer(url *common.URL) protocol.Invoker {
    90  	client, err := NewClient(url)
    91  	if err != nil {
    92  		logger.Warnf("can't dial the server: %s", url.Key())
    93  		return nil
    94  	}
    95  	invoker := NewGrpcInvoker(url, client)
    96  	gp.SetInvokers(invoker)
    97  	logger.Infof("[GRPC Protcol] Refer service: %s", url.String())
    98  	return invoker
    99  }
   100  
   101  // Destroy will destroy gRPC all invoker and exporter, so it only is called once.
   102  func (gp *GrpcProtocol) Destroy() {
   103  	logger.Infof("GrpcProtocol destroy.")
   104  
   105  	gp.serverLock.Lock()
   106  	defer gp.serverLock.Unlock()
   107  	for key, server := range gp.serverMap {
   108  		delete(gp.serverMap, key)
   109  		server.GracefulStop()
   110  	}
   111  
   112  	gp.BaseProtocol.Destroy()
   113  }
   114  
   115  // GetProtocol gets gRPC protocol, will create if null.
   116  func GetProtocol() protocol.Protocol {
   117  	if grpcProtocol == nil {
   118  		grpcProtocol = NewGRPCProtocol()
   119  	}
   120  	return grpcProtocol
   121  }