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