diff --git a/IPython/html/static/notebook/js/comm.js b/IPython/html/static/notebook/js/comm.js index 6969ef8..38fafa8 100644 --- a/IPython/html/static/notebook/js/comm.js +++ b/IPython/html/static/notebook/js/comm.js @@ -97,35 +97,35 @@ var IPython = (function (IPython) { //----------------------------------------------------------------------- var Comm = function (comm_id, target) { - this.comm_id = comm_id; + this.comm_id = comm_id || new IPython.utils.uuid(); this.target = target || 'comm'; this._msg_callback = this._open_callback = this._close_callback = null; }; // methods for sending messages - Comm.prototype.open = function (data) { + Comm.prototype.open = function (data, callbacks) { var content = { comm_id : this.comm_id, target : this.target, data : data || {}, }; - this.kernel.send_shell_message("comm_open", content); + return this.kernel.send_shell_message("comm_open", content, callbacks); }; - Comm.prototype.send = function (data) { + Comm.prototype.send = function (data, callbacks) { var content = { comm_id : this.comm_id, data : data || {}, }; - return this.kernel.send_shell_message("comm_msg", content); + return this.kernel.send_shell_message("comm_msg", content, callbacks); }; - Comm.prototype.close = function (data) { + Comm.prototype.close = function (data, callbacks) { var content = { comm_id : this.comm_id, data : data || {}, }; - return this.kernel.send_shell_message("comm_close", content); + return this.kernel.send_shell_message("comm_close", content, callbacks); }; // methods for registering callbacks for incoming messages @@ -144,7 +144,7 @@ var IPython = (function (IPython) { Comm.prototype.on_close = function (callback) { this._register_callback('close', callback); }; - + // methods for handling incoming messages Comm.prototype._maybe_callback = function (key, msg) { @@ -166,7 +166,7 @@ var IPython = (function (IPython) { IPython.CommManager = CommManager; IPython.Comm = Comm; - + return IPython; }(IPython)); diff --git a/IPython/kernel/comm/manager.py b/IPython/kernel/comm/manager.py index 981dde6..54abae6 100644 --- a/IPython/kernel/comm/manager.py +++ b/IPython/kernel/comm/manager.py @@ -11,6 +11,8 @@ # Imports #----------------------------------------------------------------------------- +import sys + from IPython.config import LoggingConfigurable from IPython.core.prompts import LazyEvaluate from IPython.core.getipython import get_ipython @@ -33,6 +35,23 @@ def lazy_keys(dikt): return LazyEvaluate(lambda d: list(d.keys())) +def with_output(method): + """method decorator for ensuring output is handled properly in a message handler + + - sets parent header before entering the method + - flushes stdout/stderr after + """ + def method_with_output(self, stream, ident, msg): + self.shell.set_parent(msg['header']) + try: + return method(self, stream, ident, msg) + finally: + sys.stdout.flush() + sys.stderr.flush() + + return method_with_output + + class CommManager(LoggingConfigurable): """Manager for Comms in the Kernel""" @@ -97,7 +116,7 @@ class CommManager(LoggingConfigurable): return comm # Message handlers - + @with_output def comm_open(self, stream, ident, msg): """Handler for comm_open messages""" content = msg['content'] @@ -117,6 +136,7 @@ class CommManager(LoggingConfigurable): comm.handle_open(msg) self.register_comm(comm) + @with_output def comm_msg(self, stream, ident, msg): """Handler for comm_msg messages""" content = msg['content'] @@ -127,6 +147,7 @@ class CommManager(LoggingConfigurable): return comm.handle_msg(msg) + @with_output def comm_close(self, stream, ident, msg): """Handler for comm_close messages""" content = msg['content']