##// END OF EJS Templates
send idle/busy on all shell messages...
MinRK -
Show More
@@ -1,15 +1,7 b''
1 """Base class to manage comms"""
1 """Base class to manage comms"""
2
2
3 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
4 # Copyright (C) 2013 The IPython Development Team
4 # Distributed under the terms of the Modified BSD License.
5 #
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
13
5
14 import sys
6 import sys
15
7
@@ -23,9 +15,6 b' from IPython.utils.traitlets import Instance, Unicode, Dict, Any'
23
15
24 from .comm import Comm
16 from .comm import Comm
25
17
26 #-----------------------------------------------------------------------------
27 # Code
28 #-----------------------------------------------------------------------------
29
18
30 def lazy_keys(dikt):
19 def lazy_keys(dikt):
31 """Return lazy-evaluated string representation of a dictionary's keys
20 """Return lazy-evaluated string representation of a dictionary's keys
@@ -36,27 +25,6 b' def lazy_keys(dikt):'
36 return LazyEvaluate(lambda d: list(d.keys()))
25 return LazyEvaluate(lambda d: list(d.keys()))
37
26
38
27
39 def with_output(method):
40 """method decorator for ensuring output is handled properly in a message handler
41
42 - sets parent header before entering the method
43 - publishes busy/idle
44 - flushes stdout/stderr after
45 """
46 def method_with_output(self, stream, ident, msg):
47 parent = msg['header']
48 self.shell.set_parent(parent)
49 self.shell.kernel._publish_status('busy', parent)
50 try:
51 return method(self, stream, ident, msg)
52 finally:
53 sys.stdout.flush()
54 sys.stderr.flush()
55 self.shell.kernel._publish_status('idle', parent)
56
57 return method_with_output
58
59
60 class CommManager(LoggingConfigurable):
28 class CommManager(LoggingConfigurable):
61 """Manager for Comms in the Kernel"""
29 """Manager for Comms in the Kernel"""
62
30
@@ -127,7 +95,6 b' class CommManager(LoggingConfigurable):'
127 return comm
95 return comm
128
96
129 # Message handlers
97 # Message handlers
130 @with_output
131 def comm_open(self, stream, ident, msg):
98 def comm_open(self, stream, ident, msg):
132 """Handler for comm_open messages"""
99 """Handler for comm_open messages"""
133 content = msg['content']
100 content = msg['content']
@@ -151,7 +118,6 b' class CommManager(LoggingConfigurable):'
151 comm.close()
118 comm.close()
152 self.unregister_comm(comm_id)
119 self.unregister_comm(comm_id)
153
120
154 @with_output
155 def comm_msg(self, stream, ident, msg):
121 def comm_msg(self, stream, ident, msg):
156 """Handler for comm_msg messages"""
122 """Handler for comm_msg messages"""
157 content = msg['content']
123 content = msg['content']
@@ -165,7 +131,6 b' class CommManager(LoggingConfigurable):'
165 except Exception:
131 except Exception:
166 self.log.error("Exception in comm_msg for %s", comm_id, exc_info=True)
132 self.log.error("Exception in comm_msg for %s", comm_id, exc_info=True)
167
133
168 @with_output
169 def comm_close(self, stream, ident, msg):
134 def comm_close(self, stream, ident, msg):
170 """Handler for comm_close messages"""
135 """Handler for comm_close messages"""
171 content = msg['content']
136 content = msg['content']
@@ -125,7 +125,7 b' class Kernel(Configurable):'
125 for msg_type in control_msg_types:
125 for msg_type in control_msg_types:
126 self.control_handlers[msg_type] = getattr(self, msg_type)
126 self.control_handlers[msg_type] = getattr(self, msg_type)
127
127
128
128
129 def dispatch_control(self, msg):
129 def dispatch_control(self, msg):
130 """dispatch control requests"""
130 """dispatch control requests"""
131 idents,msg = self.session.feed_identities(msg, copy=False)
131 idents,msg = self.session.feed_identities(msg, copy=False)
@@ -162,6 +162,10 b' class Kernel(Configurable):'
162 self.log.error("Invalid Message", exc_info=True)
162 self.log.error("Invalid Message", exc_info=True)
163 return
163 return
164
164
165 # Set the parent message for side effects.
166 self.set_parent(idents, msg)
167 self._publish_status(u'busy')
168
165 header = msg['header']
169 header = msg['header']
166 msg_id = header['msg_id']
170 msg_id = header['msg_id']
167 msg_type = msg['header']['msg_type']
171 msg_type = msg['header']['msg_type']
@@ -196,6 +200,10 b' class Kernel(Configurable):'
196 self.log.error("Exception in message handler:", exc_info=True)
200 self.log.error("Exception in message handler:", exc_info=True)
197 finally:
201 finally:
198 signal(SIGINT, sig)
202 signal(SIGINT, sig)
203
204 sys.stdout.flush()
205 sys.stderr.flush()
206 self._publish_status(u'idle')
199
207
200 def enter_eventloop(self):
208 def enter_eventloop(self):
201 """enter eventloop"""
209 """enter eventloop"""
@@ -281,7 +289,7 b' class Kernel(Configurable):'
281 self.session.send(self.iopub_socket,
289 self.session.send(self.iopub_socket,
282 u'status',
290 u'status',
283 {u'execution_state': status},
291 {u'execution_state': status},
284 parent=parent,
292 parent=parent or self._parent_header,
285 ident=self._topic('status'),
293 ident=self._topic('status'),
286 )
294 )
287
295
@@ -313,8 +321,6 b' class Kernel(Configurable):'
313 def execute_request(self, stream, ident, parent):
321 def execute_request(self, stream, ident, parent):
314 """handle an execute_request"""
322 """handle an execute_request"""
315
323
316 self._publish_status(u'busy', parent)
317
318 try:
324 try:
319 content = parent[u'content']
325 content = parent[u'content']
320 code = py3compat.cast_unicode_py2(content[u'code'])
326 code = py3compat.cast_unicode_py2(content[u'code'])
@@ -329,9 +335,6 b' class Kernel(Configurable):'
329
335
330 md = self._make_metadata(parent['metadata'])
336 md = self._make_metadata(parent['metadata'])
331
337
332 # Set the parent message of the display hook and out streams.
333 self.set_parent(ident, parent)
334
335 # Re-broadcast our input for the benefit of listening clients, and
338 # Re-broadcast our input for the benefit of listening clients, and
336 # start computing output
339 # start computing output
337 if not silent:
340 if not silent:
@@ -367,8 +370,6 b' class Kernel(Configurable):'
367 if not silent and reply_msg['content']['status'] == u'error':
370 if not silent and reply_msg['content']['status'] == u'error':
368 self._abort_queues()
371 self._abort_queues()
369
372
370 self._publish_status(u'idle', parent)
371
372 def do_execute(self, code, silent, store_history=True,
373 def do_execute(self, code, silent, store_history=True,
373 user_experssions=None, allow_stdin=False):
374 user_experssions=None, allow_stdin=False):
374 """Execute user code. Must be overridden by subclasses.
375 """Execute user code. Must be overridden by subclasses.
@@ -484,11 +485,6 b' class Kernel(Configurable):'
484 self.log.error("Got bad msg: %s", parent, exc_info=True)
485 self.log.error("Got bad msg: %s", parent, exc_info=True)
485 return
486 return
486
487
487 self._publish_status(u'busy', parent)
488
489 # Set the parent message of the display hook and out streams.
490 self.set_parent(ident, parent)
491
492 md = self._make_metadata(parent['metadata'])
488 md = self._make_metadata(parent['metadata'])
493
489
494 reply_content, result_buf = self.do_apply(content, bufs, msg_id, md)
490 reply_content, result_buf = self.do_apply(content, bufs, msg_id, md)
@@ -503,8 +499,6 b' class Kernel(Configurable):'
503 self.session.send(stream, u'apply_reply', reply_content,
499 self.session.send(stream, u'apply_reply', reply_content,
504 parent=parent, ident=ident,buffers=result_buf, metadata=md)
500 parent=parent, ident=ident,buffers=result_buf, metadata=md)
505
501
506 self._publish_status(u'idle', parent)
507
508 def do_apply(self, content, bufs, msg_id, reply_metadata):
502 def do_apply(self, content, bufs, msg_id, reply_metadata):
509 """Override in subclasses to support the IPython parallel framework.
503 """Override in subclasses to support the IPython parallel framework.
510 """
504 """
@@ -886,12 +886,17 b' This message type is used by frontends to monitor the status of the kernel.'
886 Message type: ``status``::
886 Message type: ``status``::
887
887
888 content = {
888 content = {
889 # When the kernel starts to execute code, it will enter the 'busy'
889 # When the kernel starts to handle a message, it will enter the 'busy'
890 # state and when it finishes, it will enter the 'idle' state.
890 # state and when it finishes, it will enter the 'idle' state.
891 # The kernel will publish state 'starting' exactly once at process startup.
891 # The kernel will publish state 'starting' exactly once at process startup.
892 execution_state : ('busy', 'idle', 'starting')
892 execution_state : ('busy', 'idle', 'starting')
893 }
893 }
894
894
895 .. versionchanged:: 5.0
896
897 Busy and idle messages should be sent before/after handling every shell message,
898 not just execution.
899
895 Clear output
900 Clear output
896 ------------
901 ------------
897
902
General Comments 0
You need to be logged in to leave comments. Login now