##// END OF EJS Templates
cache kernel_info reply for protocol adaptation...
MinRK -
Show More
@@ -224,8 +224,7 b' class AuthenticatedZMQStreamHandler(ZMQStreamHandler, IPythonHandler):'
224 def initialize(self):
224 def initialize(self):
225 self.session = Session(config=self.config)
225 self.session = Session(config=self.config)
226
226
227 def open(self, kernel_id):
227 def open(self, *args, **kwargs):
228 self.kernel_id = cast_unicode(kernel_id, 'ascii')
229
228
230 # start the pinging
229 # start the pinging
231 if self.ping_interval > 0:
230 if self.ping_interval > 0:
@@ -5,10 +5,11 b''
5
5
6 import json
6 import json
7 import logging
7 import logging
8 from tornado import web
8 from tornado import gen, web
9 from tornado.concurrent import Future
9
10
10 from IPython.utils.jsonutil import date_default
11 from IPython.utils.jsonutil import date_default
11 from IPython.utils.py3compat import string_types
12 from IPython.utils.py3compat import cast_unicode
12 from IPython.html.utils import url_path_join, url_escape
13 from IPython.html.utils import url_path_join, url_escape
13
14
14 from ...base.handlers import IPythonHandler, json_errors
15 from ...base.handlers import IPythonHandler, json_errors
@@ -91,17 +92,26 b' class ZMQChannelHandler(AuthenticatedZMQStreamHandler):'
91 km = self.kernel_manager
92 km = self.kernel_manager
92 meth = getattr(km, 'connect_%s' % self.channel)
93 meth = getattr(km, 'connect_%s' % self.channel)
93 self.zmq_stream = meth(self.kernel_id, identity=self.session.bsession)
94 self.zmq_stream = meth(self.kernel_id, identity=self.session.bsession)
94 # Create a kernel_info channel to query the kernel protocol version.
95 # This channel will be closed after the kernel_info reply is received.
96 self.kernel_info_channel = None
97 self.kernel_info_channel = km.connect_shell(self.kernel_id)
98 self.kernel_info_channel.on_recv(self._handle_kernel_info_reply)
99 self._request_kernel_info()
100
95
101 def _request_kernel_info(self):
96 def request_kernel_info(self):
102 """send a request for kernel_info"""
97 """send a request for kernel_info"""
103 self.log.debug("requesting kernel info")
98 km = self.kernel_manager
104 self.session.send(self.kernel_info_channel, "kernel_info_request")
99 kernel = km.get_kernel(self.kernel_id)
100 try:
101 # check for cached value
102 kernel_info = kernel._kernel_info
103 except AttributeError:
104 self.log.debug("Requesting kernel info from %s", self.kernel_id)
105 # Create a kernel_info channel to query the kernel protocol version.
106 # This channel will be closed after the kernel_info reply is received.
107 if self.kernel_info_channel is None:
108 self.kernel_info_channel = km.connect_shell(self.kernel_id)
109 self.kernel_info_channel.on_recv(self._handle_kernel_info_reply)
110 self.session.send(self.kernel_info_channel, "kernel_info_request")
111 else:
112 # use cached value, don't resend request
113 self._finish_kernel_info(kernel_info)
114 return self._kernel_info_future
105
115
106 def _handle_kernel_info_reply(self, msg):
116 def _handle_kernel_info_reply(self, msg):
107 """process the kernel_info_reply
117 """process the kernel_info_reply
@@ -113,25 +123,49 b' class ZMQChannelHandler(AuthenticatedZMQStreamHandler):'
113 msg = self.session.deserialize(msg)
123 msg = self.session.deserialize(msg)
114 except:
124 except:
115 self.log.error("Bad kernel_info reply", exc_info=True)
125 self.log.error("Bad kernel_info reply", exc_info=True)
116 self._request_kernel_info()
126 self.request_kernel_info()
117 return
127 return
118 else:
128 else:
119 if msg['msg_type'] != 'kernel_info_reply' or 'protocol_version' not in msg['content']:
129 info = msg['content']
120 self.log.error("Kernel info request failed, assuming current %s", msg['content'])
130 self.log.debug("Received kernel info: %s", info)
131 if msg['msg_type'] != 'kernel_info_reply' or 'protocol_version' not in info:
132 self.log.error("Kernel info request failed, assuming current %s", info)
121 else:
133 else:
122 protocol_version = msg['content']['protocol_version']
134 kernel = self.kernel_manager.get_kernel(self.kernel_id)
123 if protocol_version != kernel_protocol_version:
135 kernel._kernel_info = info
124 self.session.adapt_version = int(protocol_version.split('.')[0])
136 self._finish_kernel_info(info)
125 self.log.info("adapting kernel to %s" % protocol_version)
137
126 self.kernel_info_channel.close()
138 # close the kernel_info channel, we don't need it anymore
139 if self.kernel_info_channel:
140 self.kernel_info_channel.close()
127 self.kernel_info_channel = None
141 self.kernel_info_channel = None
128
142
143 def _finish_kernel_info(self, info):
144 """Finish handling kernel_info reply
145
146 Set up protocol adaptation, if needed,
147 and signal that connection can continue.
148 """
149 protocol_version = info.get('protocol_version', kernel_protocol_version)
150 if protocol_version != kernel_protocol_version:
151 self.session.adapt_version = int(protocol_version.split('.')[0])
152 self.log.info("Kernel %s speaks protocol %s", self.kernel_id, protocol_version)
153 self._kernel_info_future.set_result(info)
154
129 def initialize(self):
155 def initialize(self):
130 super(ZMQChannelHandler, self).initialize()
156 super(ZMQChannelHandler, self).initialize()
131 self.zmq_stream = None
157 self.zmq_stream = None
158 self.kernel_info_channel = None
159 self._kernel_info_future = Future()
160
161 @gen.coroutine
162 def get(self, kernel_id):
163 self.kernel_id = cast_unicode(kernel_id, 'ascii')
164 yield self.request_kernel_info()
165 super(ZMQChannelHandler, self).get(kernel_id)
132
166
133 def open(self, kernel_id):
167 def open(self, kernel_id):
134 super(ZMQChannelHandler, self).open(kernel_id)
168 super(ZMQChannelHandler, self).open()
135 try:
169 try:
136 self.create_stream()
170 self.create_stream()
137 except web.HTTPError:
171 except web.HTTPError:
General Comments 0
You need to be logged in to leave comments. Login now