|
|
|
@ -146,12 +146,36 @@ cdef _cancel( |
|
|
|
|
|
|
|
|
|
cdef _next_call_event( |
|
|
|
|
_ChannelState channel_state, grpc_completion_queue *c_completion_queue, |
|
|
|
|
on_success, deadline): |
|
|
|
|
tag, event = _latent_event(c_completion_queue, deadline) |
|
|
|
|
with channel_state.condition: |
|
|
|
|
on_success(tag) |
|
|
|
|
channel_state.condition.notify_all() |
|
|
|
|
return event |
|
|
|
|
on_success, on_failure, deadline): |
|
|
|
|
"""Block on the next event out of the completion queue. |
|
|
|
|
|
|
|
|
|
On success, `on_success` will be invoked with the tag taken from the CQ. |
|
|
|
|
In the case of a failure due to an exception raised in a signal handler, |
|
|
|
|
`on_failure` will be invoked with no arguments. Note that this situation |
|
|
|
|
can only occur on the main thread. |
|
|
|
|
|
|
|
|
|
Args: |
|
|
|
|
channel_state: The state for the channel on which the RPC is running. |
|
|
|
|
c_completion_queue: The CQ which will be polled. |
|
|
|
|
on_success: A callable object to be invoked upon successful receipt of a |
|
|
|
|
tag from the CQ. |
|
|
|
|
on_failure: A callable object to be invoked in case a Python exception is |
|
|
|
|
raised from a signal handler during polling. |
|
|
|
|
deadline: The point after which the RPC will time out. |
|
|
|
|
""" |
|
|
|
|
try: |
|
|
|
|
tag, event = _latent_event(c_completion_queue, deadline) |
|
|
|
|
# NOTE(rbellevi): This broad except enables us to clean up resources before |
|
|
|
|
# propagating any exceptions raised by signal handlers to the application. |
|
|
|
|
except: |
|
|
|
|
if on_failure is not None: |
|
|
|
|
on_failure() |
|
|
|
|
raise |
|
|
|
|
else: |
|
|
|
|
with channel_state.condition: |
|
|
|
|
on_success(tag) |
|
|
|
|
channel_state.condition.notify_all() |
|
|
|
|
return event |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO(https://github.com/grpc/grpc/issues/14569): This could be a lot simpler. |
|
|
|
@ -307,8 +331,14 @@ cdef class SegregatedCall: |
|
|
|
|
def on_success(tag): |
|
|
|
|
_process_segregated_call_tag( |
|
|
|
|
self._channel_state, self._call_state, self._c_completion_queue, tag) |
|
|
|
|
def on_failure(): |
|
|
|
|
self._call_state.due.clear() |
|
|
|
|
grpc_call_unref(self._call_state.c_call) |
|
|
|
|
self._call_state.c_call = NULL |
|
|
|
|
self._channel_state.segregated_call_states.remove(self._call_state) |
|
|
|
|
_destroy_c_completion_queue(self._c_completion_queue) |
|
|
|
|
return _next_call_event( |
|
|
|
|
self._channel_state, self._c_completion_queue, on_success, None) |
|
|
|
|
self._channel_state, self._c_completion_queue, on_success, on_failure, None) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cdef SegregatedCall _segregated_call( |
|
|
|
@ -461,8 +491,11 @@ cdef class Channel: |
|
|
|
|
queue_deadline = time.time() + 1.0 |
|
|
|
|
else: |
|
|
|
|
queue_deadline = None |
|
|
|
|
# NOTE(gnossen): It is acceptable for on_failure to be None here because |
|
|
|
|
# failure conditions can only ever happen on the main thread and this |
|
|
|
|
# method is only ever invoked on the channel spin thread. |
|
|
|
|
return _next_call_event(self._state, self._state.c_call_completion_queue, |
|
|
|
|
on_success, queue_deadline) |
|
|
|
|
on_success, None, queue_deadline) |
|
|
|
|
|
|
|
|
|
def segregated_call( |
|
|
|
|
self, int flags, method, host, object deadline, object metadata, |
|
|
|
|