##// END OF EJS Templates
Use load_class in comms instead of callbacks.
Jonathan Frederic -
Show More
@@ -1,210 +1,189 b''
1 // Copyright (c) IPython Development Team.
1 // Copyright (c) IPython Development Team.
2 // Distributed under the terms of the Modified BSD License.
2 // Distributed under the terms of the Modified BSD License.
3
3
4 define([
4 define([
5 'base/js/namespace',
5 'base/js/namespace',
6 'jquery',
6 'jquery',
7 'base/js/utils',
7 'base/js/utils',
8 ], function(IPython, $, utils) {
8 ], function(IPython, $, utils) {
9 "use strict";
9 "use strict";
10
10
11 //-----------------------------------------------------------------------
11 //-----------------------------------------------------------------------
12 // CommManager class
12 // CommManager class
13 //-----------------------------------------------------------------------
13 //-----------------------------------------------------------------------
14
14
15 var CommManager = function (kernel) {
15 var CommManager = function (kernel) {
16 this.comms = {};
16 this.comms = {};
17 this.targets = {};
17 this.targets = {};
18 if (kernel !== undefined) {
18 if (kernel !== undefined) {
19 this.init_kernel(kernel);
19 this.init_kernel(kernel);
20 }
20 }
21 };
21 };
22
22
23 CommManager.prototype.init_kernel = function (kernel) {
23 CommManager.prototype.init_kernel = function (kernel) {
24 // connect the kernel, and register message handlers
24 // connect the kernel, and register message handlers
25 this.kernel = kernel;
25 this.kernel = kernel;
26 var msg_types = ['comm_open', 'comm_msg', 'comm_close'];
26 var msg_types = ['comm_open', 'comm_msg', 'comm_close'];
27 for (var i = 0; i < msg_types.length; i++) {
27 for (var i = 0; i < msg_types.length; i++) {
28 var msg_type = msg_types[i];
28 var msg_type = msg_types[i];
29 kernel.register_iopub_handler(msg_type, $.proxy(this[msg_type], this));
29 kernel.register_iopub_handler(msg_type, $.proxy(this[msg_type], this));
30 }
30 }
31 };
31 };
32
32
33 CommManager.prototype.new_comm = function (target_name, data, callbacks, metadata) {
33 CommManager.prototype.new_comm = function (target_name, data, callbacks, metadata) {
34 // Create a new Comm, register it, and open its Kernel-side counterpart
34 // Create a new Comm, register it, and open its Kernel-side counterpart
35 // Mimics the auto-registration in `Comm.__init__` in the IPython Comm
35 // Mimics the auto-registration in `Comm.__init__` in the IPython Comm
36 var comm = new Comm(target_name);
36 var comm = new Comm(target_name);
37 this.register_comm(comm);
37 this.register_comm(comm);
38 comm.open(data, callbacks, metadata);
38 comm.open(data, callbacks, metadata);
39 return comm;
39 return comm;
40 };
40 };
41
41
42 CommManager.prototype.register_target = function (target_name, f) {
42 CommManager.prototype.register_target = function (target_name, f) {
43 // Register a target function for a given target name
43 // Register a target function for a given target name
44 this.targets[target_name] = f;
44 this.targets[target_name] = f;
45 };
45 };
46
46
47 CommManager.prototype.unregister_target = function (target_name, f) {
47 CommManager.prototype.unregister_target = function (target_name, f) {
48 // Unregister a target function for a given target name
48 // Unregister a target function for a given target name
49 delete this.targets[target_name];
49 delete this.targets[target_name];
50 };
50 };
51
51
52 CommManager.prototype.register_comm = function (comm) {
52 CommManager.prototype.register_comm = function (comm) {
53 // Register a comm in the mapping
53 // Register a comm in the mapping
54 this.comms[comm.comm_id] = comm;
54 this.comms[comm.comm_id] = comm;
55 comm.kernel = this.kernel;
55 comm.kernel = this.kernel;
56 return comm.comm_id;
56 return comm.comm_id;
57 };
57 };
58
58
59 CommManager.prototype.unregister_comm = function (comm) {
59 CommManager.prototype.unregister_comm = function (comm) {
60 // Remove a comm from the mapping
60 // Remove a comm from the mapping
61 delete this.comms[comm.comm_id];
61 delete this.comms[comm.comm_id];
62 };
62 };
63
63
64 // comm message handlers
64 // comm message handlers
65
65
66 CommManager.prototype.comm_open = function (msg) {
66 CommManager.prototype.comm_open = function (msg) {
67 var content = msg.content;
67 var content = msg.content;
68 var that = this;
68 var that = this;
69
69
70 var instantiate_comm = function(target) {
70 utils.load_class(content.target_name, content.target_module, this.targets)
71 .then(function(target) {
71 var comm = new Comm(content.target_name, content.comm_id);
72 var comm = new Comm(content.target_name, content.comm_id);
72 that.register_comm(comm);
73 that.register_comm(comm);
73 try {
74 try {
74 target(comm, msg);
75 target(comm, msg);
75 } catch (e) {
76 } catch (e) {
76 console.log("Exception opening new comm:", e, e.stack, msg);
77 console.log("Exception opening new comm:", e, e.stack, msg);
77 comm.close();
78 comm.close();
78 that.unregister_comm(comm);
79 that.unregister_comm(comm);
79 }
80 }
80 };
81 }, console.error);
81
82 if (content.target_module) {
83 // Load requirejs module for comm target
84 require([content.target_module], function(mod) {
85 var target = mod[content.target_name];
86 if (target !== undefined) {
87 instantiate_comm(target)
88 } else {
89 console.log("Comm target " + content.target_name +
90 " not found in module " + content.target_module);
91 }
92 }, function(err) { console.log(err); });
93 } else {
94 // No requirejs module specified: look for target in registry
95 var f = this.targets[content.target_name];
96 if (f === undefined) {
97 console.log("No such target registered: ", content.target_name);
98 console.log("Available targets are: ", this.targets);
99 return;
100 }
101 instantiate_comm(f)
102 }
103 };
82 };
104
83
105 CommManager.prototype.comm_close = function (msg) {
84 CommManager.prototype.comm_close = function (msg) {
106 var content = msg.content;
85 var content = msg.content;
107 var comm = this.comms[content.comm_id];
86 var comm = this.comms[content.comm_id];
108 if (comm === undefined) {
87 if (comm === undefined) {
109 return;
88 return;
110 }
89 }
111 this.unregister_comm(comm);
90 this.unregister_comm(comm);
112 try {
91 try {
113 comm.handle_close(msg);
92 comm.handle_close(msg);
114 } catch (e) {
93 } catch (e) {
115 console.log("Exception closing comm: ", e, e.stack, msg);
94 console.log("Exception closing comm: ", e, e.stack, msg);
116 }
95 }
117 };
96 };
118
97
119 CommManager.prototype.comm_msg = function (msg) {
98 CommManager.prototype.comm_msg = function (msg) {
120 var content = msg.content;
99 var content = msg.content;
121 var comm = this.comms[content.comm_id];
100 var comm = this.comms[content.comm_id];
122 if (comm === undefined) {
101 if (comm === undefined) {
123 return;
102 return;
124 }
103 }
125 try {
104 try {
126 comm.handle_msg(msg);
105 comm.handle_msg(msg);
127 } catch (e) {
106 } catch (e) {
128 console.log("Exception handling comm msg: ", e, e.stack, msg);
107 console.log("Exception handling comm msg: ", e, e.stack, msg);
129 }
108 }
130 };
109 };
131
110
132 //-----------------------------------------------------------------------
111 //-----------------------------------------------------------------------
133 // Comm base class
112 // Comm base class
134 //-----------------------------------------------------------------------
113 //-----------------------------------------------------------------------
135
114
136 var Comm = function (target_name, comm_id) {
115 var Comm = function (target_name, comm_id) {
137 this.target_name = target_name;
116 this.target_name = target_name;
138 this.comm_id = comm_id || utils.uuid();
117 this.comm_id = comm_id || utils.uuid();
139 this._msg_callback = this._close_callback = null;
118 this._msg_callback = this._close_callback = null;
140 };
119 };
141
120
142 // methods for sending messages
121 // methods for sending messages
143 Comm.prototype.open = function (data, callbacks, metadata) {
122 Comm.prototype.open = function (data, callbacks, metadata) {
144 var content = {
123 var content = {
145 comm_id : this.comm_id,
124 comm_id : this.comm_id,
146 target_name : this.target_name,
125 target_name : this.target_name,
147 data : data || {},
126 data : data || {},
148 };
127 };
149 return this.kernel.send_shell_message("comm_open", content, callbacks, metadata);
128 return this.kernel.send_shell_message("comm_open", content, callbacks, metadata);
150 };
129 };
151
130
152 Comm.prototype.send = function (data, callbacks, metadata, buffers) {
131 Comm.prototype.send = function (data, callbacks, metadata, buffers) {
153 var content = {
132 var content = {
154 comm_id : this.comm_id,
133 comm_id : this.comm_id,
155 data : data || {},
134 data : data || {},
156 };
135 };
157 return this.kernel.send_shell_message("comm_msg", content, callbacks, metadata, buffers);
136 return this.kernel.send_shell_message("comm_msg", content, callbacks, metadata, buffers);
158 };
137 };
159
138
160 Comm.prototype.close = function (data, callbacks, metadata) {
139 Comm.prototype.close = function (data, callbacks, metadata) {
161 var content = {
140 var content = {
162 comm_id : this.comm_id,
141 comm_id : this.comm_id,
163 data : data || {},
142 data : data || {},
164 };
143 };
165 return this.kernel.send_shell_message("comm_close", content, callbacks, metadata);
144 return this.kernel.send_shell_message("comm_close", content, callbacks, metadata);
166 };
145 };
167
146
168 // methods for registering callbacks for incoming messages
147 // methods for registering callbacks for incoming messages
169 Comm.prototype._register_callback = function (key, callback) {
148 Comm.prototype._register_callback = function (key, callback) {
170 this['_' + key + '_callback'] = callback;
149 this['_' + key + '_callback'] = callback;
171 };
150 };
172
151
173 Comm.prototype.on_msg = function (callback) {
152 Comm.prototype.on_msg = function (callback) {
174 this._register_callback('msg', callback);
153 this._register_callback('msg', callback);
175 };
154 };
176
155
177 Comm.prototype.on_close = function (callback) {
156 Comm.prototype.on_close = function (callback) {
178 this._register_callback('close', callback);
157 this._register_callback('close', callback);
179 };
158 };
180
159
181 // methods for handling incoming messages
160 // methods for handling incoming messages
182
161
183 Comm.prototype._maybe_callback = function (key, msg) {
162 Comm.prototype._maybe_callback = function (key, msg) {
184 var callback = this['_' + key + '_callback'];
163 var callback = this['_' + key + '_callback'];
185 if (callback) {
164 if (callback) {
186 try {
165 try {
187 callback(msg);
166 callback(msg);
188 } catch (e) {
167 } catch (e) {
189 console.log("Exception in Comm callback", e, e.stack, msg);
168 console.log("Exception in Comm callback", e, e.stack, msg);
190 }
169 }
191 }
170 }
192 };
171 };
193
172
194 Comm.prototype.handle_msg = function (msg) {
173 Comm.prototype.handle_msg = function (msg) {
195 this._maybe_callback('msg', msg);
174 this._maybe_callback('msg', msg);
196 };
175 };
197
176
198 Comm.prototype.handle_close = function (msg) {
177 Comm.prototype.handle_close = function (msg) {
199 this._maybe_callback('close', msg);
178 this._maybe_callback('close', msg);
200 };
179 };
201
180
202 // For backwards compatability.
181 // For backwards compatability.
203 IPython.CommManager = CommManager;
182 IPython.CommManager = CommManager;
204 IPython.Comm = Comm;
183 IPython.Comm = Comm;
205
184
206 return {
185 return {
207 'CommManager': CommManager,
186 'CommManager': CommManager,
208 'Comm': Comm
187 'Comm': Comm
209 };
188 };
210 });
189 });
General Comments 0
You need to be logged in to leave comments. Login now