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 }