gRPC client side connection pool in Python

3,500 views
Skip to first unread message

Angus Ma

unread,
Mar 2, 2016, 11:55:42 AM3/2/16
to grpc.io
Hi guys,

I am writing a gRPC client in Python. And I hope this client would have the connection pool feature (as a SDK for other services).

Here is my design, establishing 10 channels when the client starts up, and create a stub for each channel. When someone want to send a request to gRPC server via the client, choose a random stub from the pool. I am not sure if I'm on the right track, since there is little information about stub and channel in documents.

From my understand, channel is like a kind of connection tunnel, and stub is just a lightweight thing for transfer data. It's not necessary to share the same stub for many request, channel should be. Is that right?

All my best,

Angus

Thanks so much for developing gRPC!

Craig Tiller

unread,
Mar 2, 2016, 12:02:56 PM3/2/16
to Angus Ma, grpc.io

We are actually building this in under the banner of 'client side load balancing'. With this you'll create one channel that's connected to a set of backends, and the gRPC runtime will choose which backend to send each request to.

Initial code is in, but I wouldn't expect a full implementation to be ready for at least a few months.

In the meantime what you're describing would also work.


--
You received this message because you are subscribed to the Google Groups "grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email to grpc-io+u...@googlegroups.com.
To post to this group, send email to grp...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/grpc-io/d99eb1d3-bb90-47ed-82ce-7c0daf4b4c2c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Angus Ma

unread,
Mar 2, 2016, 12:18:42 PM3/2/16
to grpc.io, an...@killpanda.de
Hi Craig,

Thanks for you reply.

1. Is it a good idea to create many stubs in one channel as a "stub pool" for better performance? 

2. I am still confused about the difference between stub and channel. Could you explain more about them?  

Craig Tiller

unread,
Mar 2, 2016, 12:26:39 PM3/2/16
to Angus Ma, grpc.io
A channel is a collection of zero or more connections to backends, and that collection is managed for you.
A stub is a thin wrapper around a channel that provides the interface to the channel that speaks the language of the service you're accessing.

There's not much point in maintaining stub pools (they really don't do much). Channel pools are slightly interesting, but like I say - there's work underway to make that irrelevant also.

Angus Ma

unread,
Mar 2, 2016, 1:01:00 PM3/2/16
to grpc.io, an...@killpanda.de

Now I see.


As I know, "multiplexed" is a very useful feature in HTTP2. if I create channel and stub every time and then close it, it won't be a multiplexed connection. For better performance, I want to reuse connection rather than creating connection every time. Could I use singleton pattern to make a global channel? Then the whole app (including web app) will have only one connection to gRPC server. But the thing is if I code like this, there will be an error and I can't close my app.


Class GrpcClient(object):

    def __init__(self):

        self.channel = NewChannel()

self.stub = NewStub()


c = GrpcClient()


D0303 01:53:18.038069000 140735146815488 iomgr.c:96] Waiting for 1 iomgr objects to be destroyed



And also, Is there a queue or something when gRPC server processes requests? It looks like the later request/response time will be longer, or even "expired" If there is a lots of requests in only one connection.


Thanks a lot. I really appreciate your reply. that's really help!

soun...@gmail.com

unread,
Mar 2, 2016, 1:18:36 PM3/2/16
to grpc.io, an...@killpanda.de
Hello

I'm a workmate of Angus Ma, I have more details.

If I write code below

class Jt(object):
    def __init__(self):
        r = dsnparse.parse(GRPC_DSN)
        self.host = r.host
        self.port = r.port
        self.channel = implementations.insecure_channel(self.host, self.port)
        self.stub = jedi_pb2.beta_create_JediService_stub(self.channel)

    def touch(self):
        request = common_pb2.Empty()
        response = self.stub.Touch(request, _TIMEOUT_SECONDS)
        return response

j = Jt()
j.touch()

Then I can't close my app, and will be a error `D0303 01:53:18.038069000 140735146815488 iomgr.c:96] Waiting for 1 iomgr objects to be destroyed`

If I run like this, it will be ok

j = Jt()
j.touch()
del j

Then everything goes well.


在 2016年3月3日星期四 UTC+8上午1:26:39,Craig Tiller写道:
Reply all
Reply to author
Forward
0 new messages