github.com/hashicorp/go-plugin@v1.6.0/examples/bidirectional/shared/grpc.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package shared 5 6 import ( 7 "context" 8 9 hclog "github.com/hashicorp/go-hclog" 10 plugin "github.com/hashicorp/go-plugin" 11 "github.com/hashicorp/go-plugin/examples/bidirectional/proto" 12 "google.golang.org/grpc" 13 ) 14 15 // GRPCClient is an implementation of KV that talks over RPC. 16 type GRPCClient struct { 17 broker *plugin.GRPCBroker 18 client proto.CounterClient 19 } 20 21 func (m *GRPCClient) Put(key string, value int64, a AddHelper) error { 22 addHelperServer := &GRPCAddHelperServer{Impl: a} 23 24 var s *grpc.Server 25 serverFunc := func(opts []grpc.ServerOption) *grpc.Server { 26 s = grpc.NewServer(opts...) 27 proto.RegisterAddHelperServer(s, addHelperServer) 28 29 return s 30 } 31 32 brokerID := m.broker.NextId() 33 go m.broker.AcceptAndServe(brokerID, serverFunc) 34 35 _, err := m.client.Put(context.Background(), &proto.PutRequest{ 36 AddServer: brokerID, 37 Key: key, 38 Value: value, 39 }) 40 41 s.Stop() 42 return err 43 } 44 45 func (m *GRPCClient) Get(key string) (int64, error) { 46 resp, err := m.client.Get(context.Background(), &proto.GetRequest{ 47 Key: key, 48 }) 49 if err != nil { 50 return 0, err 51 } 52 53 return resp.Value, nil 54 } 55 56 // Here is the gRPC server that GRPCClient talks to. 57 type GRPCServer struct { 58 // This is the real implementation 59 Impl Counter 60 61 broker *plugin.GRPCBroker 62 } 63 64 func (m *GRPCServer) Put(ctx context.Context, req *proto.PutRequest) (*proto.Empty, error) { 65 conn, err := m.broker.Dial(req.AddServer) 66 if err != nil { 67 return nil, err 68 } 69 defer conn.Close() 70 71 a := &GRPCAddHelperClient{proto.NewAddHelperClient(conn)} 72 return &proto.Empty{}, m.Impl.Put(req.Key, req.Value, a) 73 } 74 75 func (m *GRPCServer) Get(ctx context.Context, req *proto.GetRequest) (*proto.GetResponse, error) { 76 v, err := m.Impl.Get(req.Key) 77 return &proto.GetResponse{Value: v}, err 78 } 79 80 // GRPCClient is an implementation of KV that talks over RPC. 81 type GRPCAddHelperClient struct{ client proto.AddHelperClient } 82 83 func (m *GRPCAddHelperClient) Sum(a, b int64) (int64, error) { 84 resp, err := m.client.Sum(context.Background(), &proto.SumRequest{ 85 A: a, 86 B: b, 87 }) 88 if err != nil { 89 hclog.Default().Info("add.Sum", "client", "start", "err", err) 90 return 0, err 91 } 92 return resp.R, err 93 } 94 95 // Here is the gRPC server that GRPCClient talks to. 96 type GRPCAddHelperServer struct { 97 // This is the real implementation 98 Impl AddHelper 99 } 100 101 func (m *GRPCAddHelperServer) Sum(ctx context.Context, req *proto.SumRequest) (resp *proto.SumResponse, err error) { 102 r, err := m.Impl.Sum(req.A, req.B) 103 if err != nil { 104 return nil, err 105 } 106 return &proto.SumResponse{R: r}, err 107 }