##// END OF EJS Templates
Added message throttling
Jonathan Frederic -
Show More
@@ -92,10 +92,13 b' define(["static/components/underscore/underscore-min.js",'
92 this.widget_model_types = {};
92 this.widget_model_types = {};
93 this.widget_view_types = {};
93 this.widget_view_types = {};
94 this.model_widget_views = {};
94 this.model_widget_views = {};
95 this.pending_msgs = 0;
96 this.msg_throttle = 3;
97 this.msg_buffer = {};
95
98
96 var that = this;
99 var that = this;
97 Backbone.sync = function(method, model, options, error) {
100 Backbone.sync = function(method, model, options, error) {
98 var result = that.send_sync(method, model, options);
101 var result = that.handle_sync(method, model, options);
99 if (options.success) {
102 if (options.success) {
100 options.success(result);
103 options.success(result);
101 }
104 }
@@ -207,7 +210,7 b' define(["static/components/underscore/underscore-min.js",'
207 this.updating = true;
210 this.updating = true;
208 for (var key in state) {
211 for (var key in state) {
209 if (state.hasOwnProperty(key)) {
212 if (state.hasOwnProperty(key)) {
210 if (key=="_css"){
213 if (key == "_css"){
211 comm.model.css = state[key];
214 comm.model.css = state[key];
212 } else {
215 } else {
213 comm.model.set(key, state[key]);
216 comm.model.set(key, state[key]);
@@ -227,6 +230,24 b' define(["static/components/underscore/underscore-min.js",'
227 }
230 }
228 }
231 }
229
232
233 // Handle when a msg status changes in the kernel.
234 WidgetManager.prototype.handle_status = function (msg) {
235 //execution_state : ('busy', 'idle', 'starting')
236 if (msg.content.execution_state=='idle') {
237 // Send buffer if this message caused another message to be
238 // throttled.
239 if (this.msg_throttle == --this.pending_msgs &&
240 this.msg_buffer.length > 0) {
241 var outputarea = this._get_msg_outputarea(msg);
242 var callbacks = this._make_callbacks(outputarea);
243 var data = {sync_method: 'patch', sync_data: this.msg_buffer};
244 comm.send(data, callbacks);
245 this.pending_msgs++;
246 this.msg_buffer = {};
247 }
248 }
249 }
250
230 // Get the cell output area corresponding to the comm.
251 // Get the cell output area corresponding to the comm.
231 WidgetManager.prototype._get_comm_outputarea = function (comm) {
252 WidgetManager.prototype._get_comm_outputarea = function (comm) {
232 // TODO: get element from comm instead of guessing
253 // TODO: get element from comm instead of guessing
@@ -234,34 +255,64 b' define(["static/components/underscore/underscore-min.js",'
234 return cell.output_area;
255 return cell.output_area;
235 }
256 }
236
257
258 // Get the cell output area corresponding to the msg_id.
259 WidgetManager.prototype._get_msg_outputarea = function (msg) {
260 // TODO: get element from msg_id instead of guessing
261 // msg.parent_header.msg_id
262 var cell = IPython.notebook.get_cell(IPython.notebook.get_selected_index())
263 return cell.output_area;
264 }
265
266 // Build a callback dict.
267 WidgetManager.prototype._make_callbacks = function (outputarea) {
268 var callbacks = {};
269 if (outputarea != null) {
270 callbacks = {
271 iopub : {
272 status : $.proxy(this.handle_status, this),
273 output : $.proxy(outputarea.handle_output, outputarea),
274 clear_output : $.proxy(outputarea.handle_clear_output, outputarea)}
275 };
276 }
277 return callbacks;
278 }
279
237 // Send widget state to python backend.
280 // Send widget state to python backend.
238 WidgetManager.prototype.send_sync = function (method, model, options) {
281 WidgetManager.prototype.handle_sync = function (method, model, options) {
239 var model_json = model.toJSON();
282 var model_json = model.toJSON();
240
283
241 // Only send updated state if the state hasn't been changed during an update.
284 // Only send updated state if the state hasn't been changed during an update.
242 if (!this.updating) {
285 if (!this.updating) {
243 // Create a callback for the output if the widget has an output area associate with it.
286 // Create a callback for the output if the widget has an output area associate with it.
244 var callbacks = {};
287 var callbacks = this._make_callbacks(this._get_comm_outputarea(comm));
245 var comm = model.comm;
288 var comm = model.comm;
246 var outputarea = this._get_comm_outputarea(comm);
247 if (outputarea != null) {
248 callbacks = {
249 iopub : {
250 output : $.proxy(outputarea.handle_output, outputarea),
251 clear_output : $.proxy(outputarea.handle_clear_output, outputarea)}
252 };
253 };
254
289
255 // If this is a patch operation, just send the changes.
290 if (this.pending_msgs >= this.msg_throttle) {
256 var send_json = model_json;
291 // The throttle has been exceeded, buffer the current msg so
257 if (method=='patch') {
292 // it can be sent once the kernel has finished processing
258 send_json = {};
293 // some of the existing messages.
259 for (var attr in options.attrs) {
294 if (method=='patch') {
260 send_json[attr] = options.attrs[attr];
295 for (var attr in options.attrs) {
296 this.msg_buffer[attr] = options.attrs[attr];
297 }
298 } else {
299 this.msg_buffer = $.extend({}, model_json); // Copy
300 }
301 } else {
302 // We haven't exceeded the throttle, send the message like
303 // normal. If this is a patch operation, just send the
304 // changes.
305 var send_json = model_json;
306 if (method=='patch') {
307 send_json = {};
308 for (var attr in options.attrs) {
309 send_json[attr] = options.attrs[attr];
310 }
261 }
311 }
312 var data = {sync_method: method, sync_data: send_json};
313 comm.send(data, callbacks);
314 this.pending_msgs++;
262 }
315 }
263 var data = {sync_method: method, sync_data: send_json};
264 comm.send(data, callbacks);
265 }
316 }
266
317
267 // Since the comm is a one-way communication, assume the message
318 // Since the comm is a one-way communication, assume the message
General Comments 0
You need to be logged in to leave comments. Login now