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  }