def testForkManagedThreadIsNoOp(self): def cb(): pass thread = cygrpc.ForkManagedThread(cb) thread.start() thread.join()
def _spawn_delivery(state, callbacks): delivering_thread = cygrpc.ForkManagedThread(target=_deliver, args=( state, state.connectivity, callbacks, )) delivering_thread.start() state.delivering = True
def testForkManagedThread(self): def cb(): self.assertEqual(1, _get_number_active_threads()) thread = cygrpc.ForkManagedThread(cb) thread.start() thread.join() self.assertEqual(0, _get_number_active_threads())
def testForkManagedThreadThrowsException(self): def cb(): self.assertEqual(1, _get_number_active_threads()) raise Exception("expected exception") thread = cygrpc.ForkManagedThread(cb) thread.start() thread.join() self.assertEqual(0, _get_number_active_threads())
def _run_channel_spin_thread(state): def channel_spin(): while True: cygrpc.block_if_fork_in_progress(state) event = state.channel.next_call_event() if event.completion_type == cygrpc.CompletionType.queue_timeout: continue call_completed = event.tag(event) if call_completed: with state.lock: state.managed_calls -= 1 if state.managed_calls == 0: return channel_spin_thread = cygrpc.ForkManagedThread(target=channel_spin) channel_spin_thread.setDaemon(True) channel_spin_thread.start()
def _subscribe(state, callback, try_to_connect): with state.lock: if not state.callbacks_and_connectivities and not state.polling: polling_thread = cygrpc.ForkManagedThread( target=_poll_connectivity, args=(state, state.channel, bool(try_to_connect))) polling_thread.setDaemon(True) polling_thread.start() state.polling = True state.callbacks_and_connectivities.append([callback, None]) elif not state.delivering and state.connectivity is not None: _spawn_delivery(state, (callback, )) state.try_to_connect |= bool(try_to_connect) state.callbacks_and_connectivities.append( [callback, state.connectivity]) else: state.try_to_connect |= bool(try_to_connect) state.callbacks_and_connectivities.append([callback, None])
def _consume_request_iterator(request_iterator, state, call, request_serializer, event_handler): if cygrpc.is_fork_support_enabled(): condition_wait_timeout = 1.0 else: condition_wait_timeout = None def consume_request_iterator(): # pylint: disable=too-many-branches while True: return_from_user_request_generator_invoked = False try: # The thread may die in user-code. Do not block fork for this. cygrpc.enter_user_request_generator() request = next(request_iterator) except StopIteration: break except Exception: # pylint: disable=broad-except cygrpc.return_from_user_request_generator() return_from_user_request_generator_invoked = True code = grpc.StatusCode.UNKNOWN details = 'Exception iterating requests!' _LOGGER.exception(details) call.cancel(_common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code], details) _abort(state, code, details) return finally: if not return_from_user_request_generator_invoked: cygrpc.return_from_user_request_generator() serialized_request = _common.serialize(request, request_serializer) with state.condition: if state.code is None and not state.cancelled: if serialized_request is None: code = grpc.StatusCode.INTERNAL details = 'Exception serializing request!' call.cancel( _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code], details) _abort(state, code, details) return else: operations = (cygrpc.SendMessageOperation( serialized_request, _EMPTY_FLAGS), ) operating = call.operate(operations, event_handler) if operating: state.due.add(cygrpc.OperationType.send_message) else: return while True: state.condition.wait(condition_wait_timeout) cygrpc.block_if_fork_in_progress(state) if state.code is None: if cygrpc.OperationType.send_message not in state.due: break else: return else: return with state.condition: if state.code is None: operations = ( cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS), ) operating = call.operate(operations, event_handler) if operating: state.due.add(cygrpc.OperationType.send_close_from_client) consumption_thread = cygrpc.ForkManagedThread( target=consume_request_iterator) consumption_thread.setDaemon(True) consumption_thread.start()
def _consume_request_iterator(request_iterator, state, call, request_serializer, event_handler): """Consume a request iterator supplied by the user.""" def consume_request_iterator(): # pylint: disable=too-many-branches # Iterate over the request iterator until it is exhausted or an error # condition is encountered. while True: return_from_user_request_generator_invoked = False try: # The thread may die in user-code. Do not block fork for this. cygrpc.enter_user_request_generator() request = next(request_iterator) except StopIteration: break except Exception: # pylint: disable=broad-except cygrpc.return_from_user_request_generator() return_from_user_request_generator_invoked = True code = grpc.StatusCode.UNKNOWN details = 'Exception iterating requests!' _LOGGER.exception(details) call.cancel(_common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code], details) _abort(state, code, details) return finally: if not return_from_user_request_generator_invoked: cygrpc.return_from_user_request_generator() serialized_request = _common.serialize(request, request_serializer) with state.condition: if state.code is None and not state.cancelled: if serialized_request is None: code = grpc.StatusCode.INTERNAL details = 'Exception serializing request!' call.cancel( _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE[code], details) _abort(state, code, details) return else: operations = (cygrpc.SendMessageOperation( serialized_request, _EMPTY_FLAGS),) operating = call.operate(operations, event_handler) if operating: state.due.add(cygrpc.OperationType.send_message) else: return def _done(): return (state.code is not None or cygrpc.OperationType.send_message not in state.due) _common.wait( state.condition.wait, _done, spin_cb=functools.partial( cygrpc.block_if_fork_in_progress, state)) if state.code is not None: return else: return with state.condition: if state.code is None: operations = ( cygrpc.SendCloseFromClientOperation(_EMPTY_FLAGS),) operating = call.operate(operations, event_handler) if operating: state.due.add(cygrpc.OperationType.send_close_from_client) consumption_thread = cygrpc.ForkManagedThread( target=consume_request_iterator) consumption_thread.setDaemon(True) consumption_thread.start()