Optimize blocking intercepted stream-unary calls

Change the blocking stream-unary call code path to rely
on the underlying synchronous API, as opposed to calling
the Future-based underlying async API and invoking `.result()`
on the returned Future object immediately, which can be
resource-intensive.
pull/14639/head
Mehrdad Afshari 7 years ago
parent 32919791c7
commit e2ebd89a5f
  1. 33
      src/python/grpcio/grpc/_interceptor.py

@ -218,9 +218,9 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
except Exception as exception: # pylint:disable=broad-except except Exception as exception: # pylint:disable=broad-except
return _LocalFailure(exception, sys.exc_info()[2]) return _LocalFailure(exception, sys.exc_info()[2])
call_future = self._interceptor.intercept_unary_unary( call = self._interceptor.intercept_unary_unary(
continuation, client_call_details, request) continuation, client_call_details, request)
return call_future.result(), call_future return call.result(), call
def future(self, request, timeout=None, metadata=None, credentials=None): def future(self, request, timeout=None, metadata=None, credentials=None):
client_call_details = _ClientCallDetails(self._method, timeout, client_call_details = _ClientCallDetails(self._method, timeout,
@ -281,24 +281,37 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
timeout=None, timeout=None,
metadata=None, metadata=None,
credentials=None): credentials=None):
call_future = self.future( response, ignored_call = self.with_call(
request_iterator, request_iterator,
timeout=timeout, timeout=timeout,
metadata=metadata, metadata=metadata,
credentials=credentials) credentials=credentials)
return call_future.result() return response
def with_call(self, def with_call(self,
request_iterator, request_iterator,
timeout=None, timeout=None,
metadata=None, metadata=None,
credentials=None): credentials=None):
call_future = self.future( client_call_details = _ClientCallDetails(self._method, timeout,
request_iterator, metadata, credentials)
timeout=timeout,
metadata=metadata, def continuation(new_details, request_iterator):
credentials=credentials) new_method, new_timeout, new_metadata, new_credentials = (
return call_future.result(), call_future _unwrap_client_call_details(new_details, client_call_details))
try:
response, call = self._thunk(new_method).with_call(
request_iterator,
timeout=new_timeout,
metadata=new_metadata,
credentials=new_credentials)
return _UnaryOutcome(response, call)
except Exception as exception: # pylint:disable=broad-except
return _LocalFailure(exception, sys.exc_info()[2])
call = self._interceptor.intercept_stream_unary(
continuation, client_call_details, request_iterator)
return call.result(), call
def future(self, def future(self,
request_iterator, request_iterator,

Loading…
Cancel
Save