5
\$\begingroup\$

The .proto file is as below:

syntax = "proto3";

package bamboo;

// -----------------Cart service-----------------

service CartService {
    rpc AddItem(AddItemRequest) returns (Empty) {}
    rpc GetCart(GetCartRequest) returns (Cart) {}
    rpc EmptyCart(EmptyCartRequest) returns (Empty) {}
}

message CartItem {
    string product_id = 1;
    int32  quantity = 2;
}

message AddItemRequest {
    string user_id = 1;
    CartItem item = 2;
}

message EmptyCartRequest {
    string user_id = 1;
}

message GetCartRequest {
    string user_id = 1;
}

message Cart {
    string user_id = 1;
    repeated CartItem items = 2;
}

message Empty {}

And I have a Cart service on gRPC that is as simple as below:

from grpczoo import bamboo_pb2_grpc, bamboo_pb2
from concurrent import futures
import grpc
import time


class CartService(bamboo_pb2_grpc.CartServiceServicer):
    def AddItem(self, request, context):
        print(request.user_id, request.item)
        return bamboo_pb2.Empty()


if __name__ == "__main__":
    channel = grpc.insecure_channel('127.0.0.1')
    cart_stub = bamboo_pb2_grpc.CartServiceStub(channel)

    # create gRPC server
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

    # add class to gRPC server
    service = CartService()
    bamboo_pb2_grpc.add_CartServiceServicer_to_server(service, server)

    # start server
    server.add_insecure_port('[::]:9000')
    server.start()

    # keep alive
    try:
        while True:
            time.sleep(10000)
    except KeyboardInterrupt:
            server.stop(0)

Let's assume that starting a service like above seems good when you have 40 services (We can create a base class for starting a service)

The most annoying part of the system is where I have to initiate a client when I need to send a RPC call to a service (here cart service):

import grpc

# set up server stub
from grpczoo import bamboo_pb2_grpc, bamboo_pb2

channel = grpc.insecure_channel('localhost:9000')
stub = bamboo_pb2_grpc.CartServiceStub(channel)
# form request
request = bamboo_pb2.AddItemRequest(user_id="123", item={'product_id': '21', 'quantity': 2})

# make call to server
response = stub.AddItem(request)
print(response)

As you can see for a simple RPC call like above I have to open channel to that service and form a request and then call the remote method AddItem. In a real world micro-service project I have to call at least 5 different methods and for each I have to create a channel and for the request and so on.

The question is how should I manage RPC calls to different methods when project gets bigger and I have 20 to 50 different services? The above code does not seems maintainable at all. How do you handle such cases?

\$\endgroup\$
  • \$\begingroup\$ You should change your title according to Titling your question to make it more descriptive. \$\endgroup\$ – AlexV May 8 at 18:12
0
\$\begingroup\$

Worked with gRPC client in C#. There you can initialize the client in the constructor with no additional code needed on request. It should be the same in Python.

public MyClient(IConfiguration configuration, ILogger < MyClient > logger) {
 _logger = logger;
 _configuration = configuration;
 var config = _configuration.GetGrpcConfigObject(...);
 var myConfig = config.HostName + ":" + config.Port;
 _channel = new Channel(myConfig, ChannelCredentials.Insecure);
 _client = new ServiceClient(_channel);
}

public async Task <IEnumerable<Model.Permission>> GetPermissions() {
 IEnumerable <Model.Permission> resultList = null;
 try {
   PermissionResponse response = await _client.GetPermissionsAsync(new Empty());
  resultList = _mapper.Map <IEnumerable <Permission > , IEnumerable <Model.Permission >> (response.PermissionList);

 } catch (Exception ex) {
  _logger.LogError($ "BatchSave failed:{ex}");
 }
 return resultList;
}
New contributor
user2809176 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.