You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What version of gRPC and what language are you using?
grpcio: 1.62.1
grpcio-tools: 1.62.1
What operating system (Linux, Windows,...) and version?
Linux
What runtime / compiler are you using (e.g. python version or version of gcc)
Python 3.11
What did you do?
I am working with the async api and having problems with handling client cancellations on the server side. Here's a small prototype built using this example describing the problem:
async_server.py
def callback(context: grpc.aio.ServicerContext):
logging.info("Inside callback")
logging.info(context.cancelled())
class Greeter(MultiGreeterServicer):
async def sayHello(
self, request: HelloRequest, context: grpc.aio.ServicerContext
) -> HelloReply:
logging.info("Serving sayHello request %s", request)
context.add_done_callback(callback)
try:
for i in range(10):
await asyncio.sleep(1)
yield HelloReply(message=f"Hello number {i}, {request.name}!")
except asyncio.CancelledError:
logging.info("RPC cancelled")
finally:
await asyncio.sleep(2)
logging.info("Inside finally")
async_client.py
async def run() -> None:
async with grpc.aio.insecure_channel("localhost:50051") as channel:
stub = hellostreamingworld_pb2_grpc.MultiGreeterStub(channel)
hello_stream = stub.sayHello(hellostreamingworld_pb2.HelloRequest(name="you"))
try:
while True:
response = await hello_stream.read()
if response == grpc.aio.EOF:
break
logging.info("Greeter client received from direct read: " + response.message)
await asyncio.sleep(2)
hello_stream.cancel()
except asyncio.CancelledError:
pass
if __name__ == "__main__":
logging.basicConfig()
asyncio.run(run())
What did you expect to see?
context.cancelled() should return True inside the callback function
What did you see instead?
context.cancelled() returns False inside the callback function
Anything else we should know about your project / environment?
Separate question, why does the await statement inside the finally block not throw the CancelledError like the one in the try block? What is the preferred way to handle cancellations from client side, catching the Cancelled Error and doing cleanup in finally or through callback function?
The text was updated successfully, but these errors were encountered:
In short, the client-side-cancellation is observed as an asyncio.CancelledError in method handler. Currently we recommend use except asyncio.CancelledError to caught and handle client cancel on server side.
Yes, it's the same issue and I used the approach mentioned in the SO answer, but that answer was before the cancelled and done methods were introduced in #27767.
Anyway, what would you recommend for the cleanup in this case? The cleanup is an async function as well.
What version of gRPC and what language are you using?
grpcio: 1.62.1
grpcio-tools: 1.62.1
What operating system (Linux, Windows,...) and version?
Linux
What runtime / compiler are you using (e.g. python version or version of gcc)
Python 3.11
What did you do?
I am working with the async api and having problems with handling client cancellations on the server side. Here's a small prototype built using this example describing the problem:
async_server.py
async_client.py
What did you expect to see?
context.cancelled()
should return True inside the callback functionWhat did you see instead?
context.cancelled()
returns False inside the callback functionAnything else we should know about your project / environment?
Separate question, why does the await statement inside the finally block not throw the CancelledError like the one in the try block? What is the preferred way to handle cancellations from client side, catching the Cancelled Error and doing cleanup in
finally
or through callback function?The text was updated successfully, but these errors were encountered: