Is there a way to wait until the channel is ready?
ozangungor12 opened this issue · 3 comments
Is there an implementation of channel_ready()
functionality in grpclib?
In gRPC AsyncIO API, this creates a blocking co-routine until the channel is available to connect.
async with aio.insecure_channel(('127.0.0.1', 50051)) as channel:
await channel.channel_ready()
https://grpc.github.io/grpc/python/_modules/grpc/aio/_base_channel.html#Channel.channel_ready
Thanks!
In grpclib
connection is established lazily so the only way to connect is to make a request. There is also an undocumented method await channel.__connect__()
, which can be used to explicitly create a connection before making a request, but I can't guarantee that this method wouldn't change in the future.
Thank you for the answer @vmagamedov.
So, is there a "best practice" you can suggest within grpclib, for channel connection request not to crash when server is not yet ready/available?
Essentially there should be a loop with retries. We can retry connection attempts by using undocumented Channel.__connect__
method, see #128. There is also another way: we can use health check requests to check that server is ready to serve requests (if server implements health checks protocol):
from grpclib.health.v1.health_pb2 import HealthCheckRequest
from grpclib.health.v1.health_pb2 import HealthCheckResponse
from grpclib.health.v1.health_grpc import HealthStub
...
health = HealthStub(channel)
while True:
try:
response = await health.Check(HealthCheckRequest())
except (ConnectionError, GRPCError):
pass
else:
if response.status is HealthCheckResponse.SERVING:
log.info('Connected and ready')
break
else:
log.info('Connected but not ready')
log.info('Waiting for connection retry')
await asyncio.sleep(1)
This example can be further improved to limit number of retries, to specify request timeout etc.