123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- // Copyright (c) Jupyter Development Team.
- // Distributed under the terms of the Modified BSD License.
- define([
- 'jquery',
- 'base/js/utils',
- ], function($, utils) {
- "use strict";
- //-----------------------------------------------------------------------
- // CommManager class
- //-----------------------------------------------------------------------
-
- var CommManager = function (kernel) {
- this.comms = {};
- this.targets = {};
- if (kernel !== undefined) {
- this.init_kernel(kernel);
- }
- };
-
- CommManager.prototype.init_kernel = function (kernel) {
- /**
- * connect the kernel, and register message handlers
- */
- this.kernel = kernel;
- var msg_types = ['comm_open', 'comm_msg', 'comm_close'];
- for (var i = 0; i < msg_types.length; i++) {
- var msg_type = msg_types[i];
- kernel.register_iopub_handler(msg_type, $.proxy(this[msg_type], this));
- }
- };
- CommManager.prototype.new_comm = function (target_name, data, callbacks, metadata, comm_id, buffers) {
- /**
- * Create a new Comm, register it, and open its Kernel-side counterpart
- * Mimics the auto-registration in `Comm.__init__` in the Jupyter Comm.
- *
- * argument comm_id is optional
- */
- var comm = new Comm(target_name, comm_id);
- this.register_comm(comm);
- comm.open(data, callbacks, metadata, buffers);
- return comm;
- };
-
- CommManager.prototype.register_target = function (target_name, f) {
- /**
- * Register a target function for a given target name
- */
- this.targets[target_name] = f;
- };
-
- CommManager.prototype.unregister_target = function (target_name, f) {
- /**
- * Unregister a target function for a given target name
- */
- delete this.targets[target_name];
- };
-
- CommManager.prototype.register_comm = function (comm) {
- /**
- * Register a comm in the mapping
- */
- this.comms[comm.comm_id] = Promise.resolve(comm);
- comm.kernel = this.kernel;
- return comm.comm_id;
- };
-
- CommManager.prototype.unregister_comm = function (comm) {
- /**
- * Remove a comm from the mapping
- */
- delete this.comms[comm.comm_id];
- };
-
- // comm message handlers
-
- CommManager.prototype.comm_open = function (msg) {
- var content = msg.content;
- var that = this;
- var comm_id = content.comm_id;
- this.comms[comm_id] = utils.load_class(content.target_name, content.target_module,
- this.targets).then(function(target) {
- var comm = new Comm(content.target_name, comm_id);
- comm.kernel = that.kernel;
- try {
- var response = target(comm, msg);
- } catch (e) {
- comm.close();
- that.unregister_comm(comm);
- var wrapped_error = new utils.WrappedError("Exception opening new comm", e);
- console.error(wrapped_error);
- return Promise.reject(wrapped_error);
- }
- // Regardless of the target return value, we need to
- // then return the comm
- return Promise.resolve(response).then(function() {return comm;});
- }, utils.reject('Could not open comm', true));
- return this.comms[comm_id];
- };
-
- CommManager.prototype.comm_close = function(msg) {
- var content = msg.content;
- if (this.comms[content.comm_id] === undefined) {
- console.error('Comm promise not found for comm id ' + content.comm_id);
- return;
- }
- var that = this;
- this.comms[content.comm_id] = this.comms[content.comm_id].then(function(comm) {
- that.unregister_comm(comm);
- try {
- comm.handle_close(msg);
- } catch (e) {
- console.log("Exception closing comm: ", e, e.stack, msg);
- }
- // don't return a comm, so that further .then() functions
- // get an undefined comm input
- });
- return this.comms[content.comm_id];
- };
-
- CommManager.prototype.comm_msg = function(msg) {
- var content = msg.content;
- if (this.comms[content.comm_id] === undefined) {
- console.error('Comm promise not found for comm id ' + content.comm_id);
- return;
- }
- this.comms[content.comm_id] = this.comms[content.comm_id].then(function(comm) {
- return (Promise.resolve(comm.handle_msg(msg))
- .catch(utils.reject('Exception handling comm message'))
- .then(function() {return comm;}));
- });
- return this.comms[content.comm_id];
- };
-
- //-----------------------------------------------------------------------
- // Comm base class
- //-----------------------------------------------------------------------
-
- var Comm = function (target_name, comm_id) {
- this.target_name = target_name;
- this.comm_id = comm_id || utils.uuid();
- this._msg_callback = this._close_callback = null;
- };
-
- // methods for sending messages
- Comm.prototype.open = function (data, callbacks, metadata, buffers) {
- var content = {
- comm_id : this.comm_id,
- target_name : this.target_name,
- data : data || {},
- };
- return this.kernel.send_shell_message("comm_open", content, callbacks, metadata, buffers);
- };
-
- Comm.prototype.send = function (data, callbacks, metadata, buffers) {
- var content = {
- comm_id : this.comm_id,
- data : data || {},
- };
- return this.kernel.send_shell_message("comm_msg", content, callbacks, metadata, buffers);
- };
- Comm.prototype.close = function (data, callbacks, metadata, buffers) {
- var content = {
- comm_id : this.comm_id,
- data : data || {},
- };
- return this.kernel.send_shell_message("comm_close", content, callbacks, metadata, buffers);
- };
-
- // methods for registering callbacks for incoming messages
- Comm.prototype._register_callback = function (key, callback) {
- this['_' + key + '_callback'] = callback;
- };
-
- Comm.prototype.on_msg = function (callback) {
- this._register_callback('msg', callback);
- };
-
- Comm.prototype.on_close = function (callback) {
- this._register_callback('close', callback);
- };
-
- // methods for handling incoming messages
-
- Comm.prototype._callback = function (key, msg) {
- var callback = this['_' + key + '_callback'];
- if (callback) {
- try {
- return callback(msg);
- } catch (e) {
- console.log("Exception in Comm callback", e, e.stack, msg);
- }
- }
- };
-
- Comm.prototype.handle_msg = function (msg) {
- return this._callback('msg', msg);
- };
-
- Comm.prototype.handle_close = function (msg) {
- this._callback('close', msg);
- };
-
- return {
- 'CommManager': CommManager,
- 'Comm': Comm
- };
- });
|