Show More
@@ -15,24 +15,27 b' define([' | |||||
15 | * A Kernel Class to communicate with the Python kernel |
|
15 | * A Kernel Class to communicate with the Python kernel | |
16 | * @Class Kernel |
|
16 | * @Class Kernel | |
17 | */ |
|
17 | */ | |
18 | var Kernel = function (kernel_service_url, ws_url, notebook, name) { |
|
18 | var Kernel = function (kernel_service_url, ws_url, notebook, id, name) { | |
19 | this.events = notebook.events; |
|
19 | this.events = notebook.events; | |
20 | this.kernel_id = null; |
|
20 | ||
|
21 | this.id = id; | |||
|
22 | this.name = name; | |||
|
23 | ||||
21 | this.shell_channel = null; |
|
24 | this.shell_channel = null; | |
22 | this.iopub_channel = null; |
|
25 | this.iopub_channel = null; | |
23 | this.stdin_channel = null; |
|
26 | this.stdin_channel = null; | |
|
27 | ||||
24 | this.kernel_service_url = kernel_service_url; |
|
28 | this.kernel_service_url = kernel_service_url; | |
25 | this.name = name; |
|
29 | this.kernel_url = utils.url_join_encode(this.kernel_service_url, this.id); | |
26 | this.ws_url = ws_url || IPython.utils.get_body_data("wsUrl"); |
|
30 | this.ws_url = ws_url || IPython.utils.get_body_data("wsUrl"); | |
27 | if (!this.ws_url) { |
|
31 | if (!this.ws_url) { | |
28 | // trailing 's' in https will become wss for secure web sockets |
|
32 | // trailing 's' in https will become wss for secure web sockets | |
29 | this.ws_url = location.protocol.replace('http', 'ws') + "//" + location.host; |
|
33 | this.ws_url = location.protocol.replace('http', 'ws') + "//" + location.host; | |
30 | } |
|
34 | } | |
31 | this.running = false; |
|
35 | ||
32 | this.username = "username"; |
|
36 | this.username = "username"; | |
33 | this.session_id = utils.uuid(); |
|
37 | this.session_id = utils.uuid(); | |
34 | this._msg_callbacks = {}; |
|
38 | this._msg_callbacks = {}; | |
35 | this.post = $.post; |
|
|||
36 |
|
39 | |||
37 | if (typeof(WebSocket) !== 'undefined') { |
|
40 | if (typeof(WebSocket) !== 'undefined') { | |
38 | this.WebSocket = WebSocket; |
|
41 | this.WebSocket = WebSocket; | |
@@ -89,52 +92,160 b' define([' | |||||
89 | }; |
|
92 | }; | |
90 |
|
93 | |||
91 | /** |
|
94 | /** | |
92 | * Start the Python kernel |
|
95 | * GET /api/kernels | |
93 | * @method start |
|
|||
94 | */ |
|
96 | */ | |
95 |
Kernel.prototype.st |
|
97 | Kernel.prototype.list = function (success, error) { | |
96 | params = params || {}; |
|
98 | $.ajax(this.kernel_service_url, { | |
97 | if (!this.running) { |
|
99 | processData: false, | |
98 | var qs = $.param(params); |
|
100 | cache: false, | |
99 | this.post(utils.url_join_encode(this.kernel_service_url) + '?' + qs, |
|
101 | type: "GET", | |
100 | $.proxy(this._kernel_started, this), |
|
102 | dataType: "json", | |
101 | 'json' |
|
103 | success: success, | |
102 | ); |
|
104 | error: this._on_error(error) | |
|
105 | }); | |||
|
106 | }; | |||
|
107 | ||||
|
108 | /** | |||
|
109 | * POST /api/kernels | |||
|
110 | */ | |||
|
111 | Kernel.prototype.start = function (success, error) { | |||
|
112 | var that = this; | |||
|
113 | var on_success = function (data, status, xhr) { | |||
|
114 | that._kernel_started(data); | |||
|
115 | if (success) { | |||
|
116 | success(data, status, xhr); | |||
103 | } |
|
117 | } | |
104 | }; |
|
118 | }; | |
105 |
|
119 | |||
|
120 | $.ajax(this.kernel_service_url, { | |||
|
121 | processData: false, | |||
|
122 | cache: false, | |||
|
123 | type: "POST", | |||
|
124 | dataType: "json", | |||
|
125 | success: this._on_success(on_success), | |||
|
126 | error: this._on_error(error) | |||
|
127 | }); | |||
|
128 | }; | |||
|
129 | ||||
106 | /** |
|
130 | /** | |
107 | * Restart the python kernel. |
|
131 | * GET /api/kernels/[:kernel_id] | |
108 | * |
|
|||
109 | * Emit a 'status_restarting.Kernel' event with |
|
|||
110 | * the current object as parameter |
|
|||
111 | * |
|
|||
112 | * @method restart |
|
|||
113 | */ |
|
132 | */ | |
114 |
Kernel.prototype. |
|
133 | Kernel.prototype.get_info = function (success, error) { | |
|
134 | $.ajax(this.kernel_url, { | |||
|
135 | processData: false, | |||
|
136 | cache: false, | |||
|
137 | type: "GET", | |||
|
138 | dataType: "json", | |||
|
139 | success: this._on_success(success), | |||
|
140 | error: this._on_error(error) | |||
|
141 | }); | |||
|
142 | }; | |||
|
143 | ||||
|
144 | /** | |||
|
145 | * DELETE /api/kernels/[:kernel_id] | |||
|
146 | */ | |||
|
147 | Kernel.prototype.kill = function (success, error) { | |||
|
148 | var that = this; | |||
|
149 | var on_success = function (data, status, xhr) { | |||
|
150 | that._kernel_dead(); | |||
|
151 | if (success) { | |||
|
152 | success(data, status, xhr); | |||
|
153 | } | |||
|
154 | }; | |||
|
155 | ||||
|
156 | $.ajax(this.kernel_url, { | |||
|
157 | processData: false, | |||
|
158 | cache: false, | |||
|
159 | type: "DELETE", | |||
|
160 | dataType: "json", | |||
|
161 | success: this._on_success(success), | |||
|
162 | error: this._on_error(error) | |||
|
163 | }); | |||
|
164 | }; | |||
|
165 | ||||
|
166 | /** | |||
|
167 | * POST /api/kernels/[:kernel_id]/interrupt | |||
|
168 | */ | |||
|
169 | Kernel.prototype.interrupt = function (success, error) { | |||
|
170 | this.events.trigger('status_interrupting.Kernel', {kernel: this}); | |||
|
171 | var url = utils.url_join_encode(this.kernel_url, 'interrupt'); | |||
|
172 | $.ajax(url, { | |||
|
173 | processData: false, | |||
|
174 | cache: false, | |||
|
175 | type: "POST", | |||
|
176 | dataType: "json", | |||
|
177 | success: this._on_success(success), | |||
|
178 | error: this._on_error(error) | |||
|
179 | }); | |||
|
180 | }; | |||
|
181 | ||||
|
182 | /** | |||
|
183 | * POST /api/kernels/[:kernel_id]/restart | |||
|
184 | */ | |||
|
185 | Kernel.prototype.restart = function (success, error) { | |||
115 | this.events.trigger('status_restarting.Kernel', {kernel: this}); |
|
186 | this.events.trigger('status_restarting.Kernel', {kernel: this}); | |
116 | if (this.running) { |
|
|||
117 |
|
|
187 | this.stop_channels(); | |
118 | this.post(utils.url_join_encode(this.kernel_url, "restart"), |
|
188 | ||
119 | $.proxy(this._kernel_started, this), |
|
189 | var that = this; | |
120 | 'json' |
|
190 | var on_success = function (data, status, xhr) { | |
121 | ); |
|
191 | that._handle_start_success(data, status, xhr); | |
|
192 | if (success) { | |||
|
193 | success(data, status, xhr); | |||
122 | } |
|
194 | } | |
123 | }; |
|
195 | }; | |
|
196 | var on_error = function (xhr, status, err) { | |||
|
197 | that._handle_start_failure(xhr, status, err); | |||
|
198 | if (error) { | |||
|
199 | error(xhr, status, err); | |||
|
200 | } | |||
|
201 | }; | |||
|
202 | ||||
|
203 | var url = utils.url_join_encode(this.kernel_url, 'restart'); | |||
|
204 | $.ajax(url, { | |||
|
205 | processData: false, | |||
|
206 | cache: false, | |||
|
207 | type: "POST", | |||
|
208 | dataType: "json", | |||
|
209 | success: this._on_success(success), | |||
|
210 | error: this._on_error(error) | |||
|
211 | }); | |||
|
212 | }; | |||
124 |
|
213 | |||
|
214 | Kernel.prototype._on_success = function (success) { | |||
|
215 | var that = this; | |||
|
216 | return function (data, status, xhr) { | |||
|
217 | that.id = data.id; | |||
|
218 | that.name = data.name; | |||
|
219 | that.kernel_url = utils.url_join_encode(that.kernel_service_url, that.id); | |||
|
220 | if (success) { | |||
|
221 | success(data, status, xhr); | |||
|
222 | } | |||
|
223 | }; | |||
|
224 | }; | |||
|
225 | ||||
|
226 | Kernel.prototype._on_error = function (error) { | |||
|
227 | return function (xhr, status, err) { | |||
|
228 | utils.log_ajax_error(xhr, status, err); | |||
|
229 | if (error) { | |||
|
230 | error(xhr, status, err); | |||
|
231 | } | |||
|
232 | }; | |||
|
233 | }; | |||
125 |
|
234 | |||
126 | Kernel.prototype._kernel_started = function (json) { |
|
235 | Kernel.prototype._kernel_started = function (json) { | |
127 | console.log("Kernel started: ", json.id); |
|
236 | console.log("Kernel started: ", json.id); | |
128 | this.running = true; |
|
237 | this.events.trigger('status_started.Kernel', {kernel: this}); | |
129 | this.kernel_id = json.id; |
|
|||
130 | this.kernel_url = utils.url_path_join(this.kernel_service_url, this.kernel_id); |
|
|||
131 | this.start_channels(); |
|
238 | this.start_channels(); | |
132 | }; |
|
239 | }; | |
133 |
|
240 | |||
|
241 | Kernel.prototype._kernel_dead = function () { | |||
|
242 | this.stop_channels(); | |||
|
243 | this.events.trigger('status_dead.Kernel'); | |||
|
244 | }; | |||
134 |
|
245 | |||
135 |
Kernel.prototype._w |
|
246 | Kernel.prototype._ws_closed = function(ws_url, early) { | |
136 | this.stop_channels(); |
|
247 | this.stop_channels(); | |
137 |
this.events.trigger(' |
|
248 | this.events.trigger('status_disconnected.Kernel', | |
138 | {ws_url: ws_url, kernel: this, early: early} |
|
249 | {ws_url: ws_url, kernel: this, early: early} | |
139 | ); |
|
250 | ); | |
140 | }; |
|
251 | }; | |
@@ -167,7 +278,7 b' define([' | |||||
167 | } |
|
278 | } | |
168 | already_called_onclose = true; |
|
279 | already_called_onclose = true; | |
169 | if ( ! evt.wasClean ){ |
|
280 | if ( ! evt.wasClean ){ | |
170 |
that._w |
|
281 | that._ws_closed(ws_host_url, true); | |
171 | } |
|
282 | } | |
172 | }; |
|
283 | }; | |
173 | var ws_closed_late = function(evt){ |
|
284 | var ws_closed_late = function(evt){ | |
@@ -176,7 +287,7 b' define([' | |||||
176 | } |
|
287 | } | |
177 | already_called_onclose = true; |
|
288 | already_called_onclose = true; | |
178 | if ( ! evt.wasClean ){ |
|
289 | if ( ! evt.wasClean ){ | |
179 |
that._w |
|
290 | that._ws_closed(ws_host_url, false); | |
180 | } |
|
291 | } | |
181 | }; |
|
292 | }; | |
182 | var ws_error = function(evt){ |
|
293 | var ws_error = function(evt){ | |
@@ -184,7 +295,7 b' define([' | |||||
184 | return; |
|
295 | return; | |
185 | } |
|
296 | } | |
186 | already_called_onclose = true; |
|
297 | already_called_onclose = true; | |
187 |
that._w |
|
298 | that._ws_closed(ws_host_url, false); | |
188 | }; |
|
299 | }; | |
189 | var channels = [this.shell_channel, this.iopub_channel, this.stdin_channel]; |
|
300 | var channels = [this.shell_channel, this.iopub_channel, this.stdin_channel]; | |
190 | for (var i=0; i < channels.length; i++) { |
|
301 | for (var i=0; i < channels.length; i++) { | |
@@ -216,13 +327,10 b' define([' | |||||
216 | // has the same identity |
|
327 | // has the same identity | |
217 | evt.target.send(this.session_id + ':' + document.cookie); |
|
328 | evt.target.send(this.session_id + ':' + document.cookie); | |
218 |
|
329 | |||
219 | var channels = [this.shell_channel, this.iopub_channel, this.stdin_channel]; |
|
330 | if (this.is_connected()) { | |
220 | for (var i=0; i < channels.length; i++) { |
|
|||
221 | // if any channel is not ready, don't trigger event. |
|
|||
222 | if ( channels[i].readyState !== WebSocket.OPEN ) return; |
|
|||
223 | } |
|
|||
224 | // all events ready, trigger started event. |
|
331 | // all events ready, trigger started event. | |
225 |
this.events.trigger('status_ |
|
332 | this.events.trigger('status_connected.Kernel', {kernel: this}); | |
|
333 | } | |||
226 | }; |
|
334 | }; | |
227 |
|
335 | |||
228 | /** |
|
336 | /** | |
@@ -242,8 +350,25 b' define([' | |||||
242 |
|
350 | |||
243 | // Main public methods. |
|
351 | // Main public methods. | |
244 |
|
352 | |||
|
353 | Kernel.prototype.is_connected = function () { | |||
|
354 | var channels = [this.shell_channel, this.iopub_channel, this.stdin_channel]; | |||
|
355 | for (var i=0; i < channels.length; i++) { | |||
|
356 | // if any channel is not ready, then we're not connected | |||
|
357 | if (channels[i] === null) { | |||
|
358 | return false; | |||
|
359 | } | |||
|
360 | if (channels[i].readyState !== WebSocket.OPEN) { | |||
|
361 | return false; | |||
|
362 | } | |||
|
363 | } | |||
|
364 | return true; | |||
|
365 | }; | |||
|
366 | ||||
245 | // send a message on the Kernel's shell channel |
|
367 | // send a message on the Kernel's shell channel | |
246 | Kernel.prototype.send_shell_message = function (msg_type, content, callbacks, metadata) { |
|
368 | Kernel.prototype.send_shell_message = function (msg_type, content, callbacks, metadata) { | |
|
369 | if (!this.is_connected()) { | |||
|
370 | throw new Error("kernel is not connected"); | |||
|
371 | } | |||
247 | var msg = this._get_msg(msg_type, content, metadata); |
|
372 | var msg = this._get_msg(msg_type, content, metadata); | |
248 | this.shell_channel.send(JSON.stringify(msg)); |
|
373 | this.shell_channel.send(JSON.stringify(msg)); | |
249 | this.set_callbacks_for_msg(msg.header.msg_id, callbacks); |
|
374 | this.set_callbacks_for_msg(msg.header.msg_id, callbacks); | |
@@ -289,7 +414,7 b' define([' | |||||
289 | var content = { |
|
414 | var content = { | |
290 | code : code, |
|
415 | code : code, | |
291 | cursor_pos : cursor_pos, |
|
416 | cursor_pos : cursor_pos, | |
292 |
detail_level : 0 |
|
417 | detail_level : 0 | |
293 | }; |
|
418 | }; | |
294 | return this.send_shell_message("inspect_request", content, callbacks); |
|
419 | return this.send_shell_message("inspect_request", content, callbacks); | |
295 | }; |
|
420 | }; | |
@@ -342,7 +467,6 b' define([' | |||||
342 | * Payload handlers will be passed the corresponding payload and the execute_reply message. |
|
467 | * Payload handlers will be passed the corresponding payload and the execute_reply message. | |
343 | */ |
|
468 | */ | |
344 | Kernel.prototype.execute = function (code, callbacks, options) { |
|
469 | Kernel.prototype.execute = function (code, callbacks, options) { | |
345 |
|
||||
346 | var content = { |
|
470 | var content = { | |
347 | code : code, |
|
471 | code : code, | |
348 | silent : true, |
|
472 | silent : true, | |
@@ -379,37 +503,17 b' define([' | |||||
379 | } |
|
503 | } | |
380 | var content = { |
|
504 | var content = { | |
381 | code : code, |
|
505 | code : code, | |
382 |
cursor_pos : cursor_pos |
|
506 | cursor_pos : cursor_pos | |
383 | }; |
|
507 | }; | |
384 | return this.send_shell_message("complete_request", content, callbacks); |
|
508 | return this.send_shell_message("complete_request", content, callbacks); | |
385 | }; |
|
509 | }; | |
386 |
|
510 | |||
387 |
|
||||
388 | Kernel.prototype.interrupt = function () { |
|
|||
389 | if (this.running) { |
|
|||
390 | this.events.trigger('status_interrupting.Kernel', {kernel: this}); |
|
|||
391 | this.post(utils.url_join_encode(this.kernel_url, "interrupt")); |
|
|||
392 | } |
|
|||
393 | }; |
|
|||
394 |
|
||||
395 |
|
||||
396 | Kernel.prototype.kill = function (success, error) { |
|
|||
397 | if (this.running) { |
|
|||
398 | this.running = false; |
|
|||
399 | var settings = { |
|
|||
400 | cache : false, |
|
|||
401 | type : "DELETE", |
|
|||
402 | success : success, |
|
|||
403 | error : error || utils.log_ajax_error, |
|
|||
404 | }; |
|
|||
405 | $.ajax(utils.url_join_encode(this.kernel_url), settings); |
|
|||
406 | this.stop_channels(); |
|
|||
407 | } |
|
|||
408 | }; |
|
|||
409 |
|
||||
410 | Kernel.prototype.send_input_reply = function (input) { |
|
511 | Kernel.prototype.send_input_reply = function (input) { | |
|
512 | if (!this.is_connected()) { | |||
|
513 | throw new Error("kernel is not connected"); | |||
|
514 | } | |||
411 | var content = { |
|
515 | var content = { | |
412 |
value : input |
|
516 | value : input | |
413 | }; |
|
517 | }; | |
414 | this.events.trigger('input_reply.Kernel', {kernel: this, content:content}); |
|
518 | this.events.trigger('input_reply.Kernel', {kernel: this, content:content}); | |
415 | var msg = this._get_msg("input_reply", content); |
|
519 | var msg = this._get_msg("input_reply", content); |
General Comments 0
You need to be logged in to leave comments.
Login now