def frontend_request(blocking=True, timeout=None): """ Send a request to the frontend. If blocking is True, The return value will be returned. """ if not get_ipython().kernel.frontend_comm.is_open(): raise CommError("Can't make a request to a closed comm") # Get a reply from the last frontend to have sent a message return get_ipython().kernel.frontend_call(blocking=blocking, broadcast=False, timeout=timeout)
def _get_call_return_value(self, call_dict, call_data, comm_id): """ Interupt the kernel if needed. """ settings = call_dict['settings'] blocking = 'blocking' in settings and settings['blocking'] if not self.kernel_client.is_alive(): if blocking: raise RuntimeError("Kernel is dead") else: # The user has other problems logger.info( "Dropping message because kernel is dead: ", str(call_dict) ) return settings = call_dict['settings'] interrupt = 'interrupt' in settings and settings['interrupt'] interrupt = interrupt or blocking # Need to make sure any blocking call is replied rapidly. if interrupt and not self.comm_channel_connected(): # Ask again for comm config self.remote_call()._send_comm_config() # Can not interrupt if comm not connected interrupt = False logger.debug( "Dropping interrupt because comm is disconnected: " + str(call_dict) ) if blocking: raise CommError("Cannot block on a disconnected comm") try: with self.comm_channel_manager( comm_id, queue_message=not interrupt): return super(KernelComm, self)._get_call_return_value( call_dict, call_data, comm_id) except RuntimeError as e: if blocking: raise else: # The user has other problems logger.info( "Dropping message because of exception: ", str(e), str(call_dict) ) return
def comm_channel_manager(self, comm_id, queue_message=False): """Use comm_channel instead of shell_channel.""" if queue_message: # Send without comm_channel yield return if not self.comm_channel_connected(): # Ask again for comm config self.remote_call()._send_comm_config() raise CommError("Comm not connected.") id_list = self.get_comm_id_list(comm_id) for comm_id in id_list: self._comms[comm_id]['comm']._send_channel = ( self.kernel_client.comm_channel) try: yield finally: for comm_id in id_list: self._comms[comm_id]['comm']._send_channel = ( self.kernel_client.shell_channel)
def _wait_reply(self, call_id, call_name, timeout): """Wait until the frontend replies to a request.""" if call_id in self._reply_inbox: return # There is no get_ident in Py2 if not PY2 and self._main_thread_id != threading.get_ident(): # We can't call kernel.do_one_iteration from this thread. # And we have no reason to think the main thread is not busy. raise CommError("Can't make blocking calls from non-main threads.") t_start = time.time() while call_id not in self._reply_inbox: if time.time() > t_start + timeout: raise TimeoutError( "Timeout while waiting for '{}' reply".format(call_name)) priority = 0 while priority is not None: priority = self.kernel.do_one_iteration() if priority is not None: # For Python2 priority = priority.result()