From 6f0ffef2e94f24475b6197ad920ab287ce8050e8 Mon Sep 17 00:00:00 2001 From: Lidi Zheng Date: Wed, 18 Dec 2019 16:15:37 -0800 Subject: [PATCH] Resolve a TODO and handle one more cancellation corner case --- .../grpcio/grpc/experimental/aio/_call.py | 21 ++++++++++--------- .../grpcio_tests/tests_aio/unit/call_test.py | 4 ---- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/python/grpcio/grpc/experimental/aio/_call.py b/src/python/grpcio/grpc/experimental/aio/_call.py index 96415fa9521..7acb5494b4b 100644 --- a/src/python/grpcio/grpc/experimental/aio/_call.py +++ b/src/python/grpcio/grpc/experimental/aio/_call.py @@ -308,16 +308,17 @@ class UnaryUnaryCall(Call, _base_call.UnaryUnaryCall): _LOCAL_CANCELLATION_DETAILS, None, None)) def __await__(self) -> ResponseType: - """Wait till the ongoing RPC request finishes. - - Returns: - Response of the RPC call. - - Raises: - RpcError: Indicating that the RPC terminated with non-OK status. - asyncio.CancelledError: Indicating that the RPC was canceled. - """ - response = yield from self._call + """Wait till the ongoing RPC request finishes.""" + try: + response = yield from self._call + except asyncio.CancelledError: + # Even if we converted all other CancelledError, there is still + # this corner case. If the application cancels immediately after + # the Call object is created, we will observe this + # `CancelledError`. + if not self.cancelled(): + self.cancel() + raise _create_rpc_error(_EMPTY_METADATA, self._status.result()) return response diff --git a/src/python/grpcio_tests/tests_aio/unit/call_test.py b/src/python/grpcio_tests/tests_aio/unit/call_test.py index c0a7fa17017..cecce1c79d5 100644 --- a/src/python/grpcio_tests/tests_aio/unit/call_test.py +++ b/src/python/grpcio_tests/tests_aio/unit/call_test.py @@ -121,10 +121,6 @@ class TestUnaryUnaryCall(AioTestBase): self.assertFalse(call.cancelled()) - # TODO(https://github.com/grpc/grpc/issues/20869) remove sleep. - # Force the loop to execute the RPC task. - await asyncio.sleep(0) - self.assertTrue(call.cancel()) self.assertFalse(call.cancel())