Reputation: 1286
If a gRPC client starts before the server, it exits with an exception. The application I am working on starts a bunch of servers and clients (near) simultaneously, however, and I have to be robust with respect to execution order. If the client starts before the server, I want it to wait until the server shows up.
I modified the HelloWorld python client example as follows:
done = False
while not done:
try:
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'), timeout=1)
print("Greeter client received: " + response.message)
done = True
except:
print('Waiting for server connect...')
time.sleep(1)
so now if I start the client before the server, I get the 'Waiting for server connect...' message scrolling up my terminal window as expected. Then I start the server, and it connects... eventually. In fact it takes about ten seconds before the 'Hello you' messages appears, which is surprisingly long. Why might it be so slow, and is there a robust way to check for server connection?
Upvotes: 5
Views: 18417
Reputation: 560
I believe what you are looking for is Wait-for-Ready semantics.
As of 2018, this is built-in for Python via the wait_for_ready
flag. The grpc GitHub source has a few examples: https://github.com/grpc/grpc/tree/master/examples/python/wait_for_ready
Translating your question directly, you'd want something like this:
response = stub.SayHello(
helloworld_pb2.HelloRequest(name='you'),
timeout=1,
wait_for_ready=True
)
print("Greeter client received: " + response.message)
wait_for_ready
was introduced for Python in 2018, version 1.17.0, and graduated from "experimental" state in 2023 with version 1.53.0
Upvotes: 2
Reputation: 3956
import grpc
TIMEOUT_SEC = 15
def grpc_server_on(channel) -> bool:
try:
grpc.channel_ready_future(channel).result(timeout=TIMEOUT_SEC)
return True
except grpc.FutureTimeoutError:
return False
The channel_ready_future
function allows the client to wait for a specified timeout duration (in seconds) for the server to be ready. If our client times out, it raises.
Upvotes: 9
Reputation: 2131
Take a look at ChannelConnectivity - I am a go programmer but it should be the same in python. What I do is create while/for loop and when the "ChannelConnectivity" is set to "READY" I create the client from the connection and then continue.
Upvotes: 5