##// END OF EJS Templates
avoid race condition when deleting/starting sessions...
MinRK -
Show More
@@ -54,9 +54,19 b' define(['
54 return;
54 return;
55 }
55 }
56 var ks = this.kernelspecs[kernel_name];
56 var ks = this.kernelspecs[kernel_name];
57 try {
58 this.notebook.start_session(kernel_name);
59 } catch (e) {
60 if (e.name === 'SessionAlreadyStarting') {
61 console.log("Cannot change kernel while waiting for pending session start.");
62 } else {
63 // unhandled error
64 throw e;
65 }
66 // only trigger spec_changed if change was successful
67 return;
68 }
57 this.events.trigger('spec_changed.Kernel', ks);
69 this.events.trigger('spec_changed.Kernel', ks);
58 this.notebook.session.delete();
59 this.notebook.start_session(kernel_name);
60 };
70 };
61
71
62 KernelSelector.prototype.bind_events = function() {
72 KernelSelector.prototype.bind_events = function() {
@@ -157,12 +157,13 b' define(['
157 }
157 }
158 });
158 });
159 this.element.find('#kill_and_exit').click(function () {
159 this.element.find('#kill_and_exit').click(function () {
160 that.notebook.session.delete();
160 var close_window = function () {
161 setTimeout(function(){
162 // allow closing of new tabs in Chromium, impossible in FF
161 // allow closing of new tabs in Chromium, impossible in FF
163 window.open('', '_self', '');
162 window.open('', '_self', '');
164 window.close();
163 window.close();
165 }, 500);
164 };
165 // finish with close on success or failure
166 that.notebook.session.delete(close_window, close_window);
166 });
167 });
167 // Edit
168 // Edit
168 this.element.find('#cut_cell').click(function () {
169 this.element.find('#cut_cell').click(function () {
@@ -62,6 +62,7 b' define(['
62 this.save_widget = options.save_widget;
62 this.save_widget = options.save_widget;
63 this.tooltip = new tooltip.Tooltip(this.events);
63 this.tooltip = new tooltip.Tooltip(this.events);
64 this.ws_url = options.ws_url;
64 this.ws_url = options.ws_url;
65 this._session_starting = false;
65 // default_kernel_name is a temporary measure while we implement proper
66 // default_kernel_name is a temporary measure while we implement proper
66 // kernel selection and delayed start. Do not rely on it.
67 // kernel selection and delayed start. Do not rely on it.
67 this.default_kernel_name = 'python';
68 this.default_kernel_name = 'python';
@@ -1525,9 +1526,38 b' define(['
1525 * @method start_session
1526 * @method start_session
1526 */
1527 */
1527 Notebook.prototype.start_session = function (kernel_name) {
1528 Notebook.prototype.start_session = function (kernel_name) {
1529 var that = this;
1528 if (kernel_name === undefined) {
1530 if (kernel_name === undefined) {
1529 kernel_name = this.default_kernel_name;
1531 kernel_name = this.default_kernel_name;
1530 }
1532 }
1533 if (this._session_starting) {
1534 throw new session.SessionAlreadyStarting();
1535 }
1536 this._session_starting = true;
1537
1538 if (this.session !== null) {
1539 var s = this.session;
1540 this.session = null;
1541 // need to start the new session in a callback after delete,
1542 // because javascript does not guarantee the ordering of AJAX requests (?!)
1543 s.delete(function () {
1544 // on successful delete, start new session
1545 that._session_starting = false;
1546 that.start_session(kernel_name);
1547 }, function (jqXHR, status, error) {
1548 // log the failed delete, but still create a new session
1549 // 404 just means it was already deleted by someone else,
1550 // but other errors are possible.
1551 utils.log_ajax_error(jqXHR, status, error);
1552 that._session_starting = false;
1553 that.start_session(kernel_name);
1554 }
1555 );
1556 return;
1557 }
1558
1559
1560
1531 this.session = new session.Session({
1561 this.session = new session.Session({
1532 base_url: this.base_url,
1562 base_url: this.base_url,
1533 ws_url: this.ws_url,
1563 ws_url: this.ws_url,
@@ -1539,7 +1569,10 b' define(['
1539 kernel_name: kernel_name,
1569 kernel_name: kernel_name,
1540 notebook: this});
1570 notebook: this});
1541
1571
1542 this.session.start($.proxy(this._session_started, this));
1572 this.session.start(
1573 $.proxy(this._session_started, this),
1574 $.proxy(this._session_start_failed, this)
1575 );
1543 };
1576 };
1544
1577
1545
1578
@@ -1548,7 +1581,8 b' define(['
1548 * comm manager to the widget manager
1581 * comm manager to the widget manager
1549 *
1582 *
1550 */
1583 */
1551 Notebook.prototype._session_started = function(){
1584 Notebook.prototype._session_started = function (){
1585 this._session_starting = false;
1552 this.kernel = this.session.kernel;
1586 this.kernel = this.session.kernel;
1553 var ncells = this.ncells();
1587 var ncells = this.ncells();
1554 for (var i=0; i<ncells; i++) {
1588 for (var i=0; i<ncells; i++) {
@@ -1558,7 +1592,11 b' define(['
1558 }
1592 }
1559 }
1593 }
1560 };
1594 };
1561
1595 Notebook.prototype._session_start_failed = function (jqxhr, status, error){
1596 this._session_starting = false;
1597 utils.log_ajax_error(jqxhr, status, error);
1598 };
1599
1562 /**
1600 /**
1563 * Prompt the user to restart the IPython kernel.
1601 * Prompt the user to restart the IPython kernel.
1564 *
1602 *
@@ -385,13 +385,14 b' define(['
385 };
385 };
386
386
387
387
388 Kernel.prototype.kill = function () {
388 Kernel.prototype.kill = function (success, faiure) {
389 if (this.running) {
389 if (this.running) {
390 this.running = false;
390 this.running = false;
391 var settings = {
391 var settings = {
392 cache : false,
392 cache : false,
393 type : "DELETE",
393 type : "DELETE",
394 error : utils.log_ajax_error,
394 success : success,
395 error : error || utils.log_ajax_error,
395 };
396 };
396 $.ajax(utils.url_join_encode(this.kernel_url), settings);
397 $.ajax(utils.url_join_encode(this.kernel_url), settings);
397 this.stop_channels();
398 this.stop_channels();
@@ -21,7 +21,7 b' define(['
21 this.ws_url = options.ws_url;
21 this.ws_url = options.ws_url;
22 };
22 };
23
23
24 Session.prototype.start = function(callback) {
24 Session.prototype.start = function (success, error) {
25 var that = this;
25 var that = this;
26 var model = {
26 var model = {
27 notebook : {
27 notebook : {
@@ -40,11 +40,11 b' define(['
40 dataType : "json",
40 dataType : "json",
41 success : function (data, status, xhr) {
41 success : function (data, status, xhr) {
42 that._handle_start_success(data);
42 that._handle_start_success(data);
43 if (callback) {
43 if (success) {
44 callback(data, status, xhr);
44 success(data, status, xhr);
45 }
45 }
46 },
46 },
47 error : utils.log_ajax_error,
47 error : error || utils.log_ajax_error,
48 };
48 };
49 var url = utils.url_join_encode(this.base_url, 'api/sessions');
49 var url = utils.url_join_encode(this.base_url, 'api/sessions');
50 $.ajax(url, settings);
50 $.ajax(url, settings);
@@ -71,13 +71,14 b' define(['
71 $.ajax(url, settings);
71 $.ajax(url, settings);
72 };
72 };
73
73
74 Session.prototype.delete = function() {
74 Session.prototype.delete = function (success, error) {
75 var settings = {
75 var settings = {
76 processData : false,
76 processData : false,
77 cache : false,
77 cache : false,
78 type : "DELETE",
78 type : "DELETE",
79 dataType : "json",
79 dataType : "json",
80 error : utils.log_ajax_error,
80 success : success,
81 error : error || utils.log_ajax_error,
81 };
82 };
82 this.kernel.running = false;
83 this.kernel.running = false;
83 this.kernel.stop_channels();
84 this.kernel.stop_channels();
@@ -119,8 +120,18 b' define(['
119 this.kernel.kill();
120 this.kernel.kill();
120 };
121 };
121
122
123 var SessionAlreadyStarting = function (message) {
124 this.name = "SessionAlreadyStarting";
125 this.message = (message || "");
126 };
127
128 SessionAlreadyStarting.prototype = Error.prototype;
129
122 // For backwards compatability.
130 // For backwards compatability.
123 IPython.Session = Session;
131 IPython.Session = Session;
124
132
125 return {'Session': Session};
133 return {
134 Session: Session,
135 SessionAlreadyStarting: SessionAlreadyStarting,
136 };
126 });
137 });
General Comments 0
You need to be logged in to leave comments. Login now