Show More
@@ -34,7 +34,7 import uuid | |||
|
34 | 34 | from IPython.config.application import boolean_flag |
|
35 | 35 | from IPython.config.configurable import Configurable |
|
36 | 36 | from IPython.core.profiledir import ProfileDir |
|
37 |
from IPython.kernel.blocking import BlockingKernel |
|
|
37 | from IPython.kernel.blocking import BlockingKernelClient | |
|
38 | 38 | from IPython.kernel import KernelManager |
|
39 | 39 | from IPython.kernel import tunnel_to_kernel, find_connection_file, swallow_argv |
|
40 | 40 | from IPython.utils.path import filefind |
@@ -144,7 +144,8 class IPythonConsoleApp(Configurable): | |||
|
144 | 144 | classes = classes |
|
145 | 145 | flags = Dict(flags) |
|
146 | 146 | aliases = Dict(aliases) |
|
147 |
kernel_manager_class = |
|
|
147 | kernel_manager_class = KernelManager | |
|
148 | kernel_client_class = BlockingKernelClient | |
|
148 | 149 | |
|
149 | 150 | kernel_argv = List(Unicode) |
|
150 | 151 | # frontend flags&aliases to be stripped when building kernel_argv |
@@ -328,6 +329,9 class IPythonConsoleApp(Configurable): | |||
|
328 | 329 | |
|
329 | 330 | def init_kernel_manager(self): |
|
330 | 331 | # Don't let Qt or ZMQ swallow KeyboardInterupts. |
|
332 | if self.existing: | |
|
333 | self.kernel_manager = None | |
|
334 | return | |
|
331 | 335 | signal.signal(signal.SIGINT, signal.SIG_DFL) |
|
332 | 336 | |
|
333 | 337 | # Create a KernelManager and start a kernel. |
@@ -346,8 +350,29 class IPythonConsoleApp(Configurable): | |||
|
346 | 350 | elif self.sshserver: |
|
347 | 351 | # ssh, write new connection file |
|
348 | 352 | self.kernel_manager.write_connection_file() |
|
353 | ||
|
354 | # in case KM defaults / ssh writing changes things: | |
|
355 | km = self.kernel_manager | |
|
356 | self.shell_port=km.shell_port | |
|
357 | self.iopub_port=km.iopub_port | |
|
358 | self.stdin_port=km.stdin_port | |
|
359 | self.hb_port=km.hb_port | |
|
360 | self.connection_file = km.connection_file | |
|
361 | ||
|
349 | 362 | atexit.register(self.kernel_manager.cleanup_connection_file) |
|
350 | self.kernel_manager.start_channels() | |
|
363 | ||
|
364 | def init_kernel_client(self): | |
|
365 | self.kernel_client = self.kernel_client_class( | |
|
366 | shell_port=self.shell_port, | |
|
367 | iopub_port=self.iopub_port, | |
|
368 | stdin_port=self.stdin_port, | |
|
369 | hb_port=self.hb_port, | |
|
370 | connection_file=self.connection_file, | |
|
371 | config=self.config, | |
|
372 | ) | |
|
373 | ||
|
374 | self.kernel_client.start_channels() | |
|
375 | ||
|
351 | 376 | |
|
352 | 377 | |
|
353 | 378 | def initialize(self, argv=None): |
@@ -359,4 +384,5 class IPythonConsoleApp(Configurable): | |||
|
359 | 384 | default_secure(self.config) |
|
360 | 385 | self.init_ssh() |
|
361 | 386 | self.init_kernel_manager() |
|
387 | self.init_kernel_client() | |
|
362 | 388 |
@@ -114,7 +114,10 class ZMQTerminalIPythonApp(TerminalIPythonApp, IPythonConsoleApp): | |||
|
114 | 114 | signal.signal(signal.SIGINT, self.handle_sigint) |
|
115 | 115 | self.shell = ZMQTerminalInteractiveShell.instance(config=self.config, |
|
116 | 116 | display_banner=False, profile_dir=self.profile_dir, |
|
117 |
ipython_dir=self.ipython_dir, |
|
|
117 | ipython_dir=self.ipython_dir, | |
|
118 | kernel_manager=self.kernel_manager, | |
|
119 | kernel_client=self.kernel_client, | |
|
120 | ) | |
|
118 | 121 | |
|
119 | 122 | def init_gui_pylab(self): |
|
120 | 123 | # no-op, because we don't want to import matplotlib in the frontend. |
@@ -9,9 +9,9 class ZMQCompleter(object): | |||
|
9 | 9 | state=0,1,2,... When state=0 it should compute ALL the completion matches, |
|
10 | 10 | and then return them for each value of state.""" |
|
11 | 11 | |
|
12 |
def __init__(self, shell, |
|
|
12 | def __init__(self, shell, client): | |
|
13 | 13 | self.shell = shell |
|
14 |
self. |
|
|
14 | self.client = client | |
|
15 | 15 | self.matches = [] |
|
16 | 16 | |
|
17 | 17 | def complete_request(self,text): |
@@ -20,10 +20,10 class ZMQCompleter(object): | |||
|
20 | 20 | |
|
21 | 21 | # send completion request to kernel |
|
22 | 22 | # Give the kernel up to 0.5s to respond |
|
23 |
msg_id = self. |
|
|
23 | msg_id = self.client.shell_channel.complete(text=text, line=line, | |
|
24 | 24 | cursor_pos=cursor_pos) |
|
25 | 25 | |
|
26 |
msg = self. |
|
|
26 | msg = self.client.shell_channel.get_msg(timeout=0.5) | |
|
27 | 27 | if msg['parent_header']['msg_id'] == msg_id: |
|
28 | 28 | return msg["content"]["matches"] |
|
29 | 29 | return [] |
@@ -106,8 +106,9 class ZMQTerminalInteractiveShell(TerminalInteractiveShell): | |||
|
106 | 106 | ) |
|
107 | 107 | |
|
108 | 108 | def __init__(self, *args, **kwargs): |
|
109 |
self. |
|
|
110 | self.session_id = self.km.session.session | |
|
109 | self.manager = kwargs.pop('kernel_manager') | |
|
110 | self.client = kwargs.pop('kernel_client') | |
|
111 | self.session_id = self.client.session.session | |
|
111 | 112 | super(ZMQTerminalInteractiveShell, self).__init__(*args, **kwargs) |
|
112 | 113 | |
|
113 | 114 | def init_completer(self): |
@@ -121,7 +122,7 class ZMQTerminalInteractiveShell(TerminalInteractiveShell): | |||
|
121 | 122 | from IPython.core.completerlib import (module_completer, |
|
122 | 123 | magic_run_completer, cd_completer) |
|
123 | 124 | |
|
124 |
self.Completer = ZMQCompleter(self, self. |
|
|
125 | self.Completer = ZMQCompleter(self, self.client) | |
|
125 | 126 | |
|
126 | 127 | |
|
127 | 128 | self.set_hook('complete_command', module_completer, str_key = 'import') |
@@ -156,18 +157,18 class ZMQTerminalInteractiveShell(TerminalInteractiveShell): | |||
|
156 | 157 | |
|
157 | 158 | self._executing = True |
|
158 | 159 | # flush stale replies, which could have been ignored, due to missed heartbeats |
|
159 |
while self. |
|
|
160 |
self. |
|
|
160 | while self.client.shell_channel.msg_ready(): | |
|
161 | self.client.shell_channel.get_msg() | |
|
161 | 162 | # shell_channel.execute takes 'hidden', which is the inverse of store_hist |
|
162 |
msg_id = self. |
|
|
163 |
while not self. |
|
|
163 | msg_id = self.client.shell_channel.execute(cell, not store_history) | |
|
164 | while not self.client.shell_channel.msg_ready() and self.client.is_alive(): | |
|
164 | 165 | try: |
|
165 | 166 | self.handle_stdin_request(timeout=0.05) |
|
166 | 167 | except Empty: |
|
167 | 168 | # display intermediate print statements, etc. |
|
168 | 169 | self.handle_iopub() |
|
169 | 170 | pass |
|
170 |
if self. |
|
|
171 | if self.client.shell_channel.msg_ready(): | |
|
171 | 172 | self.handle_execute_reply(msg_id) |
|
172 | 173 | self._executing = False |
|
173 | 174 | |
@@ -176,7 +177,7 class ZMQTerminalInteractiveShell(TerminalInteractiveShell): | |||
|
176 | 177 | #----------------- |
|
177 | 178 | |
|
178 | 179 | def handle_execute_reply(self, msg_id): |
|
179 |
msg = self. |
|
|
180 | msg = self.client.shell_channel.get_msg() | |
|
180 | 181 | if msg["parent_header"].get("msg_id", None) == msg_id: |
|
181 | 182 | |
|
182 | 183 | self.handle_iopub() |
@@ -211,8 +212,8 class ZMQTerminalInteractiveShell(TerminalInteractiveShell): | |||
|
211 | 212 | sub_msg: message receive from kernel in the sub socket channel |
|
212 | 213 | capture by kernel manager. |
|
213 | 214 | """ |
|
214 |
while self. |
|
|
215 |
sub_msg = self. |
|
|
215 | while self.client.iopub_channel.msg_ready(): | |
|
216 | sub_msg = self.client.iopub_channel.get_msg() | |
|
216 | 217 | msg_type = sub_msg['header']['msg_type'] |
|
217 | 218 | parent = sub_msg["parent_header"] |
|
218 | 219 | if (not parent) or self.session_id == parent['session']: |
@@ -298,7 +299,7 class ZMQTerminalInteractiveShell(TerminalInteractiveShell): | |||
|
298 | 299 | def handle_stdin_request(self, timeout=0.1): |
|
299 | 300 | """ Method to capture raw_input |
|
300 | 301 | """ |
|
301 |
msg_rep = self. |
|
|
302 | msg_rep = self.client.stdin_channel.get_msg(timeout=timeout) | |
|
302 | 303 | # in case any iopub came while we were waiting: |
|
303 | 304 | self.handle_iopub() |
|
304 | 305 | if self.session_id == msg_rep["parent_header"].get("session"): |
@@ -325,8 +326,8 class ZMQTerminalInteractiveShell(TerminalInteractiveShell): | |||
|
325 | 326 | |
|
326 | 327 | # only send stdin reply if there *was not* another request |
|
327 | 328 | # or execution finished while we were reading. |
|
328 |
if not (self. |
|
|
329 |
self. |
|
|
329 | if not (self.client.stdin_channel.msg_ready() or self.client.shell_channel.msg_ready()): | |
|
330 | self.client.stdin_channel.input(raw_data) | |
|
330 | 331 | |
|
331 | 332 | def mainloop(self, display_banner=False): |
|
332 | 333 | while True: |
@@ -344,10 +345,10 class ZMQTerminalInteractiveShell(TerminalInteractiveShell): | |||
|
344 | 345 | def wait_for_kernel(self, timeout=None): |
|
345 | 346 | """method to wait for a kernel to be ready""" |
|
346 | 347 | tic = time.time() |
|
347 |
self. |
|
|
348 | self.client.hb_channel.unpause() | |
|
348 | 349 | while True: |
|
349 | 350 | self.run_cell('1', False) |
|
350 |
if self. |
|
|
351 | if self.client.hb_channel.is_beating(): | |
|
351 | 352 | # heart failure was not the reason this returned |
|
352 | 353 | break |
|
353 | 354 | else: |
@@ -389,13 +390,14 class ZMQTerminalInteractiveShell(TerminalInteractiveShell): | |||
|
389 | 390 | # ask_exit callback. |
|
390 | 391 | |
|
391 | 392 | while not self.exit_now: |
|
392 |
if not self. |
|
|
393 | if not self.client.is_alive(): | |
|
393 | 394 | # kernel died, prompt for action or exit |
|
394 | action = "restart" if self.km.has_kernel else "wait for restart" | |
|
395 | ||
|
396 | action = "restart" if self.manager else "wait for restart" | |
|
395 | 397 | ans = self.ask_yes_no("kernel died, %s ([y]/n)?" % action, default='y') |
|
396 | 398 | if ans: |
|
397 |
if self. |
|
|
398 |
self. |
|
|
399 | if self.manager: | |
|
400 | self.manager.restart_kernel(True) | |
|
399 | 401 | self.wait_for_kernel(3) |
|
400 | 402 | else: |
|
401 | 403 | self.exit_now = True |
@@ -203,7 +203,7 class ShellChannel(ZMQSocketChannel): | |||
|
203 | 203 | |
|
204 | 204 | Subclasses should override this method to handle incoming messages. |
|
205 | 205 | It is important to remember that this method is called in the thread |
|
206 | so that some logic must be done to ensure that the application leve | |
|
206 | so that some logic must be done to ensure that the application level | |
|
207 | 207 | handlers are called in the application thread. |
|
208 | 208 | """ |
|
209 | 209 | raise NotImplementedError('call_handlers must be defined in a subclass.') |
General Comments 0
You need to be logged in to leave comments.
Login now