4

I was trying to see if it's possible to run different instances of the same service on a single GRPC server, but it looks like I'm not able to do so. So I was wondering if I was doing anything wrong with my test, or if it's not possible at all.

My test is based on examples/python/multiplex from grpc repo:

Service:

class _GreeterServicer(helloworld_pb2_grpc.GreeterServicer):

    def __init__(self, greeter):
        self.greeter = greeter

    def SayHello(self, request, context):
        return helloworld_pb2.HelloReply(
            message='Hello, {}! This is {}!'.format(request.name, self.greeter))

Server:

def serve():
    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
    helloworld_pb2_grpc.add_GreeterServicer_to_server(_GreeterServicer("John"),
                                                      server)
    helloworld_pb2_grpc.add_GreeterServicer_to_server(_GreeterServicer("Jim"),
                                                      server)
    server.add_insecure_port('[::]:50051')
    server.start()
    server.wait_for_termination()

Client:

def run():
    for _ in range(10):
        with grpc.insecure_channel('localhost:50051') as channel:
            greeter_stub = helloworld_pb2_grpc.GreeterStub(channel)
            greeter_response = greeter_stub.SayHello(
                helloworld_pb2.HelloRequest(name='you'))
            print("Greeter client received: " + greeter_response.message)

Since I'm opening a new channel for each iteration, I was expecting to get an output with a mix of "Hello, you! This is Jim!" and "Hello, you! This is John!", but instead I'm getting only:

Greeter client received: Hello, you! This is John!
Greeter client received: Hello, you! This is John!
Greeter client received: Hello, you! This is John!
Greeter client received: Hello, you! This is John!
Greeter client received: Hello, you! This is John!
Greeter client received: Hello, you! This is John!
Greeter client received: Hello, you! This is John!
Greeter client received: Hello, you! This is John!
Greeter client received: Hello, you! This is John!
Greeter client received: Hello, you! This is John!

that is, the first service of GreeterServicer I added to the server, which supposedly ignore the second servicer instance.

So, my question is if it's even possible to something like this on a single server and if there is a best practice to handle such scenarios where I would want two mostly identical services, parameterized differently (e.g. different grpc servers? that would imply a load balancing between the two instances).

In my particular scenario, the parameters to be passed are some credentials to be used within the service implementation, and my goal would be, then, to have these two identical services running concurrently so that the end user has no idea there are multiple instances.

fedexist
  • 155
  • 2
  • 12
  • See: https://github.com/grpc/grpc/tree/master/examples/python/multiplex – DazWilkin Apr 30 '20 at 21:28
  • 1
    This may be of interest too: https://grpc.io/blog/grpc-load-balancing/ – DazWilkin Apr 30 '20 at 21:28
  • Thank you for the grpc balancing link, that should be useful if I have no choice other than use multiple servers. About the multiplex, that was the first thing I looked up when staring at this issue, but as far as I see, those multiplex examples are about using multiple *different* servicers in a single server. – fedexist May 01 '20 at 08:47
  • I'm slightly unclear on your need. With Python, you're limited to a single thread unless you use something that'll run you multiple workers, right? IIUC multiplexing the same service across two threads, should give you the ability to get "This is Jim" back too. – DazWilkin May 01 '20 at 21:24
  • I mean, if the server is running multiple workers, I'd expect to have multiple services with no issue. Looking at the code of the multiplexing examples, I'm failing to see how this kind of multithreading is achieved (other than the threadpoolexecutor passed to the server). In those examples, a GreeterService and a RouteGuideService are added to the same server and, ok, no issue with that, again adding multiple GreeterServices is not working. For this reason, my question was if I was missing anything (server/client options) in how a grpc server works, or If I should implement this myself. – fedexist May 02 '20 at 11:37

1 Answers1

2

The gRPC-Go implementation explicits disallows registering the same service multiple times on a grpc.Server object. Code

I'm not very familiar with the Python implementation, but I would assume it also does something similar. Does the call to add_GreeterServicer_to_server return a status or error?

  • No error is thrown, no value is returned, but as you point out and as far as I understand now, a service could be considered pretty much a singleton within a single grpc server, because of the mapping done between the HTTP/2 path and the service implementation. So, following the test I've run, I could either have multiple servers each configured with a service and different name or a single server where, within the service, I switch between names. – fedexist May 06 '20 at 22:10