Is it possible to run multiple instances of same service on single GRPC server?
Asked Answered
O

1

6

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.

Orizaba answered 30/4, 2020 at 16:21 Comment(5)
See: github.com/grpc/grpc/tree/master/examples/python/multiplexMemoir
This may be of interest too: grpc.io/blog/grpc-load-balancingMemoir
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.Orizaba
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.Memoir
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.Orizaba
C
3

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?

Corundum answered 6/5, 2020 at 17:36 Comment(1)
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.Orizaba

© 2022 - 2025 — McMap. All rights reserved.