##// END OF EJS Templates
Add option to interrupt kernel after execution timeout
Jessica B. Hamrick -
Show More
@@ -4,13 +4,14 b''
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 import os
6 import os
7 from textwrap import dedent
7
8
8 try:
9 try:
9 from queue import Empty # Py 3
10 from queue import Empty # Py 3
10 except ImportError:
11 except ImportError:
11 from Queue import Empty # Py 2
12 from Queue import Empty # Py 2
12
13
13 from IPython.utils.traitlets import List, Unicode
14 from IPython.utils.traitlets import List, Unicode, Bool
14
15
15 from IPython.nbformat.v4 import output_from_msg
16 from IPython.nbformat.v4 import output_from_msg
16 from .base import Preprocessor
17 from .base import Preprocessor
@@ -26,6 +27,17 b' class ExecutePreprocessor(Preprocessor):'
26 help="The time to wait (in seconds) for output from executions."
27 help="The time to wait (in seconds) for output from executions."
27 )
28 )
28
29
30 interrupt_on_timeout = Bool(
31 False, config=True,
32 help=dedent(
33 """
34 If execution of a cell times out, interrupt the kernel and
35 continue executing other cells rather than throwing an error and
36 stopping.
37 """
38 )
39 )
40
29 extra_arguments = List(Unicode)
41 extra_arguments = List(Unicode)
30
42
31 def preprocess(self, nb, resources):
43 def preprocess(self, nb, resources):
@@ -33,16 +45,22 b' class ExecutePreprocessor(Preprocessor):'
33 if path == '':
45 if path == '':
34 path = None
46 path = None
35
47
36 from IPython.kernel import run_kernel
48 from IPython.kernel.manager import start_new_kernel
37 kernel_name = nb.metadata.get('kernelspec', {}).get('name', 'python')
49 kernel_name = nb.metadata.get('kernelspec', {}).get('name', 'python')
38 self.log.info("Executing notebook with kernel: %s" % kernel_name)
50 self.log.info("Executing notebook with kernel: %s" % kernel_name)
39 with run_kernel(kernel_name=kernel_name,
51 self.km, self.kc = start_new_kernel(
52 kernel_name=kernel_name,
40 extra_arguments=self.extra_arguments,
53 extra_arguments=self.extra_arguments,
41 stderr=open(os.devnull, 'w'),
54 stderr=open(os.devnull, 'w'),
42 cwd=path) as kc:
55 cwd=path)
43 self.kc = kc
44 self.kc.allow_stdin = False
56 self.kc.allow_stdin = False
57
58 try:
45 nb, resources = super(ExecutePreprocessor, self).preprocess(nb, resources)
59 nb, resources = super(ExecutePreprocessor, self).preprocess(nb, resources)
60 finally:
61 self.kc.stop_channels()
62 self.km.shutdown_kernel(now=True)
63
46 return nb, resources
64 return nb, resources
47
65
48 def preprocess_cell(self, cell, resources, cell_index):
66 def preprocess_cell(self, cell, resources, cell_index):
@@ -69,7 +87,13 b' class ExecutePreprocessor(Preprocessor):'
69 msg = self.kc.shell_channel.get_msg(timeout=self.timeout)
87 msg = self.kc.shell_channel.get_msg(timeout=self.timeout)
70 except Empty:
88 except Empty:
71 self.log.error("Timeout waiting for execute reply")
89 self.log.error("Timeout waiting for execute reply")
90 if self.interrupt_on_timeout:
91 self.log.error("Interrupting kernel")
92 self.km.interrupt_kernel()
93 break
94 else:
72 raise
95 raise
96
73 if msg['parent_header'].get('msg_id') == msg_id:
97 if msg['parent_header'].get('msg_id') == msg_id:
74 break
98 break
75 else:
99 else:
General Comments 0
You need to be logged in to leave comments. Login now