@@ -240,14 +240,10 @@ def should_handle(self, stream, msg, idents):
240240 return True
241241
242242 @gen .coroutine
243- def dispatch_shell (self , msg ):
243+ def dispatch_shell (self , msg , idents = None ):
244244 """dispatch shell requests"""
245- idents , msg = self .session .feed_identities (msg , copy = False )
246- try :
247- msg = self .session .deserialize (msg , content = True , copy = False )
248- except :
249- self .log .error ("Invalid Message" , exc_info = True )
250- return
245+ if idents is None :
246+ idents = []
251247
252248 # Set the parent message for side effects.
253249 self .set_parent (idents , msg , channel = 'shell' )
@@ -403,15 +399,42 @@ def dispatch_queue(self):
403399 def _message_counter_default (self ):
404400 return itertools .count ()
405401
406- def schedule_dispatch (self , dispatch , * args ):
402+ def should_dispatch_immediately (
403+ self , msg , idents , dispatch
404+ ):
405+ """
406+ This provides a hook for dispatching incoming messages
407+ from the frontend immediately, and out of order.
408+
409+ It could be used to allow asynchronous messages from
410+ GUIs to be processed.
411+ """
412+ return False
413+
414+ def schedule_dispatch (self , msg , dispatch ):
407415 """schedule a message for dispatch"""
416+
417+ idents , msg = self .session .feed_identities (msg , copy = False )
418+ try :
419+ msg = self .session .deserialize (msg , content = True , copy = False )
420+ except :
421+ self .log .error ("Invalid shell message" , exc_info = True )
422+ return
423+
424+ new_args = (msg , idents )
425+
426+ if self .should_dispatch_immediately (
427+ msg , idents , dispatch
428+ ):
429+ return self .io_loop .add_callback (dispatch , * new_args )
430+
408431 idx = next (self ._message_counter )
409432
410433 self .msg_queue .put_nowait (
411434 (
412435 idx ,
413436 dispatch ,
414- args ,
437+ new_args ,
415438 )
416439 )
417440 # ensure the eventloop wakes up
0 commit comments