##// END OF EJS Templates
Add missing 'history_tail_reply' signal to QtKernelManager.
epatters -
Show More
@@ -1,242 +1,243
1 1 """ Defines a KernelManager that provides signals and slots.
2 2 """
3 3
4 4 # System library imports.
5 5 from IPython.external.qt import QtCore
6 6
7 7 # IPython imports.
8 8 from IPython.utils.traitlets import Type
9 9 from IPython.zmq.kernelmanager import KernelManager, SubSocketChannel, \
10 10 XReqSocketChannel, RepSocketChannel, HBSocketChannel
11 11 from util import MetaQObjectHasTraits, SuperQObject
12 12
13 13
14 14 class SocketChannelQObject(SuperQObject):
15 15
16 16 # Emitted when the channel is started.
17 17 started = QtCore.Signal()
18 18
19 19 # Emitted when the channel is stopped.
20 20 stopped = QtCore.Signal()
21 21
22 22 #---------------------------------------------------------------------------
23 23 # 'ZmqSocketChannel' interface
24 24 #---------------------------------------------------------------------------
25 25
26 26 def start(self):
27 27 """ Reimplemented to emit signal.
28 28 """
29 29 super(SocketChannelQObject, self).start()
30 30 self.started.emit()
31 31
32 32 def stop(self):
33 33 """ Reimplemented to emit signal.
34 34 """
35 35 super(SocketChannelQObject, self).stop()
36 36 self.stopped.emit()
37 37
38 38
39 39 class QtXReqSocketChannel(SocketChannelQObject, XReqSocketChannel):
40 40
41 41 # Emitted when any message is received.
42 42 message_received = QtCore.Signal(object)
43 43
44 44 # Emitted when a reply has been received for the corresponding request
45 45 # type.
46 46 execute_reply = QtCore.Signal(object)
47 47 complete_reply = QtCore.Signal(object)
48 48 object_info_reply = QtCore.Signal(object)
49 history_tail_reply = QtCore.Signal(object)
49 50
50 51 # Emitted when the first reply comes back.
51 52 first_reply = QtCore.Signal()
52 53
53 54 # Used by the first_reply signal logic to determine if a reply is the
54 55 # first.
55 56 _handlers_called = False
56 57
57 58 #---------------------------------------------------------------------------
58 59 # 'XReqSocketChannel' interface
59 60 #---------------------------------------------------------------------------
60 61
61 62 def call_handlers(self, msg):
62 63 """ Reimplemented to emit signals instead of making callbacks.
63 64 """
64 65 # Emit the generic signal.
65 66 self.message_received.emit(msg)
66 67
67 68 # Emit signals for specialized message types.
68 69 msg_type = msg['msg_type']
69 70 signal = getattr(self, msg_type, None)
70 71 if signal:
71 72 signal.emit(msg)
72 73
73 74 if not self._handlers_called:
74 75 self.first_reply.emit()
75 76 self._handlers_called = True
76 77
77 78 #---------------------------------------------------------------------------
78 79 # 'QtXReqSocketChannel' interface
79 80 #---------------------------------------------------------------------------
80 81
81 82 def reset_first_reply(self):
82 83 """ Reset the first_reply signal to fire again on the next reply.
83 84 """
84 85 self._handlers_called = False
85 86
86 87
87 88 class QtSubSocketChannel(SocketChannelQObject, SubSocketChannel):
88 89
89 90 # Emitted when any message is received.
90 91 message_received = QtCore.Signal(object)
91 92
92 93 # Emitted when a message of type 'stream' is received.
93 94 stream_received = QtCore.Signal(object)
94 95
95 96 # Emitted when a message of type 'pyin' is received.
96 97 pyin_received = QtCore.Signal(object)
97 98
98 99 # Emitted when a message of type 'pyout' is received.
99 100 pyout_received = QtCore.Signal(object)
100 101
101 102 # Emitted when a message of type 'pyerr' is received.
102 103 pyerr_received = QtCore.Signal(object)
103 104
104 105 # Emitted when a message of type 'display_data' is received
105 106 display_data_received = QtCore.Signal(object)
106 107
107 108 # Emitted when a crash report message is received from the kernel's
108 109 # last-resort sys.excepthook.
109 110 crash_received = QtCore.Signal(object)
110 111
111 112 # Emitted when a shutdown is noticed.
112 113 shutdown_reply_received = QtCore.Signal(object)
113 114
114 115 #---------------------------------------------------------------------------
115 116 # 'SubSocketChannel' interface
116 117 #---------------------------------------------------------------------------
117 118
118 119 def call_handlers(self, msg):
119 120 """ Reimplemented to emit signals instead of making callbacks.
120 121 """
121 122 # Emit the generic signal.
122 123 self.message_received.emit(msg)
123 124 # Emit signals for specialized message types.
124 125 msg_type = msg['msg_type']
125 126 signal = getattr(self, msg_type + '_received', None)
126 127 if signal:
127 128 signal.emit(msg)
128 129 elif msg_type in ('stdout', 'stderr'):
129 130 self.stream_received.emit(msg)
130 131
131 132 def flush(self):
132 133 """ Reimplemented to ensure that signals are dispatched immediately.
133 134 """
134 135 super(QtSubSocketChannel, self).flush()
135 136 QtCore.QCoreApplication.instance().processEvents()
136 137
137 138
138 139 class QtRepSocketChannel(SocketChannelQObject, RepSocketChannel):
139 140
140 141 # Emitted when any message is received.
141 142 message_received = QtCore.Signal(object)
142 143
143 144 # Emitted when an input request is received.
144 145 input_requested = QtCore.Signal(object)
145 146
146 147 #---------------------------------------------------------------------------
147 148 # 'RepSocketChannel' interface
148 149 #---------------------------------------------------------------------------
149 150
150 151 def call_handlers(self, msg):
151 152 """ Reimplemented to emit signals instead of making callbacks.
152 153 """
153 154 # Emit the generic signal.
154 155 self.message_received.emit(msg)
155 156
156 157 # Emit signals for specialized message types.
157 158 msg_type = msg['msg_type']
158 159 if msg_type == 'input_request':
159 160 self.input_requested.emit(msg)
160 161
161 162
162 163 class QtHBSocketChannel(SocketChannelQObject, HBSocketChannel):
163 164
164 165 # Emitted when the kernel has died.
165 166 kernel_died = QtCore.Signal(object)
166 167
167 168 #---------------------------------------------------------------------------
168 169 # 'HBSocketChannel' interface
169 170 #---------------------------------------------------------------------------
170 171
171 172 def call_handlers(self, since_last_heartbeat):
172 173 """ Reimplemented to emit signals instead of making callbacks.
173 174 """
174 175 # Emit the generic signal.
175 176 self.kernel_died.emit(since_last_heartbeat)
176 177
177 178
178 179 class QtKernelManager(KernelManager, SuperQObject):
179 180 """ A KernelManager that provides signals and slots.
180 181 """
181 182
182 183 __metaclass__ = MetaQObjectHasTraits
183 184
184 185 # Emitted when the kernel manager has started listening.
185 186 started_channels = QtCore.Signal()
186 187
187 188 # Emitted when the kernel manager has stopped listening.
188 189 stopped_channels = QtCore.Signal()
189 190
190 191 # Use Qt-specific channel classes that emit signals.
191 192 sub_channel_class = Type(QtSubSocketChannel)
192 193 xreq_channel_class = Type(QtXReqSocketChannel)
193 194 rep_channel_class = Type(QtRepSocketChannel)
194 195 hb_channel_class = Type(QtHBSocketChannel)
195 196
196 197 #---------------------------------------------------------------------------
197 198 # 'KernelManager' interface
198 199 #---------------------------------------------------------------------------
199 200
200 201 #------ Kernel process management ------------------------------------------
201 202
202 203 def start_kernel(self, *args, **kw):
203 204 """ Reimplemented for proper heartbeat management.
204 205 """
205 206 if self._xreq_channel is not None:
206 207 self._xreq_channel.reset_first_reply()
207 208 super(QtKernelManager, self).start_kernel(*args, **kw)
208 209
209 210 #------ Channel management -------------------------------------------------
210 211
211 212 def start_channels(self, *args, **kw):
212 213 """ Reimplemented to emit signal.
213 214 """
214 215 super(QtKernelManager, self).start_channels(*args, **kw)
215 216 self.started_channels.emit()
216 217
217 218 def stop_channels(self):
218 219 """ Reimplemented to emit signal.
219 220 """
220 221 super(QtKernelManager, self).stop_channels()
221 222 self.stopped_channels.emit()
222 223
223 224 @property
224 225 def xreq_channel(self):
225 226 """ Reimplemented for proper heartbeat management.
226 227 """
227 228 if self._xreq_channel is None:
228 229 self._xreq_channel = super(QtKernelManager, self).xreq_channel
229 230 self._xreq_channel.first_reply.connect(self._first_reply)
230 231 return self._xreq_channel
231 232
232 233 #---------------------------------------------------------------------------
233 234 # Protected interface
234 235 #---------------------------------------------------------------------------
235 236
236 237 def _first_reply(self):
237 238 """ Unpauses the heartbeat channel when the first reply is received on
238 239 the execute channel. Note that this will *not* start the heartbeat
239 240 channel if it is not already running!
240 241 """
241 242 if self._hb_channel is not None:
242 243 self._hb_channel.unpause()
General Comments 0
You need to be logged in to leave comments. Login now