##// END OF EJS Templates
More work on autorestarting.
Brian Granger -
Show More
@@ -41,22 +41,37 b' class KernelRestarter(LoggingConfigurable):'
41 41 help="""Kernel heartbeat interval in seconds."""
42 42 )
43 43
44 _pcallback = None
45
44 46 def __init__(self, **kwargs):
45 47 super(KernelRestarter, self).__init__(**kwargs)
46 48
47 49 def start(self):
48 self.pc = ioloop.PeriodicCallback(self.poll, self.time_to_dead, self.ioloop)
49 self.pc.start()
50 """Start the polling of the kernel."""
51 if self._pcallback is None:
52 self._pcallback = ioloop.PeriodicCallback(
53 self._poll, 1000*self.time_to_dead, self.ioloop
54 )
55 self._pcallback.start()
56
57 def stop(self):
58 """Stop the kernel polling."""
59 if self._pcallback is not None:
60 self._pcallback.stop()
50 61
51 def poll(self):
62 def clear(self):
63 """Clear the underlying PeriodicCallback."""
64 self.stop()
65 if self._pcallback is not None:
66 self._pcallback = None
67
68 def _poll(self):
52 69 if not self.kernel_manager.is_alive():
53 70 self.stop()
54 71 # This restart event should leave the connection file in place so
55 72 # the ports are the same. Because this takes place below the
56 73 # MappingKernelManager, the kernel_id will also remain the same.
74 self.log('KernelRestarter: restarting kernel')
57 75 self.kernel_manager.restart_kernel(now=True);
58 76 self.start()
59 77
60 def stop(self):
61 self.pc.stop()
62 self.pc = None
@@ -23,12 +23,15 b' import uuid'
23 23
24 24 import zmq
25 25 from zmq.eventloop.zmqstream import ZMQStream
26 from zmq.eventloop import ioloop
26 27
27 28 from IPython.config.configurable import LoggingConfigurable
28 29 from IPython.utils.importstring import import_item
29 30 from IPython.utils.traitlets import (
30 Instance, Dict, Unicode, Any, DottedObjectName,
31 Instance, Dict, Unicode, Any, DottedObjectName, Bool
31 32 )
33 # from IPython.kernel.kernelrestarter import KernelRestarter
34
32 35 #-----------------------------------------------------------------------------
33 36 # Classes
34 37 #-----------------------------------------------------------------------------
@@ -61,7 +64,7 b' class MultiKernelManager(LoggingConfigurable):'
61 64 def _loop_default(self):
62 65 return ioloop.IOLoop.instance()
63 66
64 autorestart = Bool(True, config=True,
67 autorestart = Bool(False, config=True,
65 68 help="""Should we autorestart kernels that die."""
66 69 )
67 70
@@ -83,18 +86,29 b' class MultiKernelManager(LoggingConfigurable):'
83 86 def __contains__(self, kernel_id):
84 87 return kernel_id in self._kernels
85 88
86 def start_watching(self, kernel_id):
87 km = self.get_kernel(kernel_id):
89 def start_restarter(self, kernel_id):
90 km = self.get_kernel(kernel_id)
88 91 if self.autorestart:
89 kr = KernelRestarter(
90 kernel_manager=km, loop=self.loop,
91 config=self.config, log=self.log
92 )
92 kr = self._restarters.get(kernel_id, None)
93 if kr is None:
94 kr = KernelRestarter(
95 kernel_manager=km, loop=self.loop,
96 config=self.config, log=self.log
97 )
98 self._restarters[kernel_id] = kr
93 99 kr.start()
94 self._restarters[kernel_id] = kr
95 100
96 def stop_watching(self, kernel_id):
101 def stop_restarter(self, kernel_id):
102 if self.autorestart:
103 kr = self._restarters.get(kernel_id, None)
104 if kr is not None:
105 kr.stop()
97 106
107 def clear_restarter(self, kernel_id):
108 if self.autorestart:
109 kr = self._restarters.pop(kernel_id, None)
110 if kr is not None:
111 kr.stop()
98 112
99 113 def start_kernel(self, **kwargs):
100 114 """Start a new kernel.
@@ -121,7 +135,7 b' class MultiKernelManager(LoggingConfigurable):'
121 135 # start just the shell channel, needed for graceful restart
122 136 km.start_channels(shell=True, iopub=False, stdin=False, hb=False)
123 137 self._kernels[kernel_id] = km
124 self.start_watching(kernel_id)
138 self.start_restarter(kernel_id)
125 139 return kernel_id
126 140
127 141 def shutdown_kernel(self, kernel_id, now=False):
@@ -135,11 +149,11 b' class MultiKernelManager(LoggingConfigurable):'
135 149 Should the kernel be shutdown forcibly using a signal.
136 150 """
137 151 k = self.get_kernel(kernel_id)
138 self.stop_watching(kernel_id)
152 self.stop_restarter(kernel_id)
139 153 k.shutdown_kernel(now=now)
140 154 k.shell_channel.stop()
141 155 del self._kernels[kernel_id]
142 self.remove_watching(kernel_id)
156 self.clear_restarter(kernel_id)
143 157
144 158 def shutdown_all(self, now=False):
145 159 """Shutdown all kernels."""
@@ -178,9 +192,9 b' class MultiKernelManager(LoggingConfigurable):'
178 192 The id of the kernel to interrupt.
179 193 """
180 194 km = self.get_kernel(kernel_id)
181 self.stop_watching()
195 self.stop_restarter(kernel_id)
182 196 km.restart_kernel()
183 self.start_watching()
197 self.start_restarter(kernel_id)
184 198
185 199 def is_alive(self, kernel_id):
186 200 """Is the kernel alive.
General Comments 0
You need to be logged in to leave comments. Login now