Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: lib/messaging.js

Issue 29338275: Issue 3499 - Create a clean messaging API for internal use (Closed)
Left Patch Set: Allow duplicate callbacks, introduce isPromise() function, minor changes Created March 21, 2016, 3:30 p.m.
Right Patch Set: Don't store all responses unnecessarily Created March 21, 2016, 8:40 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « lib/child/bootstrap.js ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2016 Eyeo GmbH 3 * Copyright (C) 2006-2016 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 { 45 {
46 Cu.reportError("Unexpected message manager, impossible to send message"); 46 Cu.reportError("Unexpected message manager, impossible to send message");
47 return 0; 47 return 0;
48 } 48 }
49 } 49 }
50 50
51 function sendSyncMessage(messageManager, messageName, payload) 51 function sendSyncMessage(messageManager, messageName, payload)
52 { 52 {
53 let request = {messageName, payload}; 53 let request = {messageName, payload};
54 let responses = messageManager.sendRpcMessage(MESSAGE_NAME, request); 54 let responses = messageManager.sendRpcMessage(MESSAGE_NAME, request);
55 return flattenResponses(responses, messageName); 55 let processor = new ResponseProcessor(messageName);
56 }
57
58 function flattenResponses(responses, messageName)
59 {
60 let result = undefined;
61 for (let response of responses) 56 for (let response of responses)
57 processor.add(response);
58 return processor.value;
59 }
60
61 function ResponseProcessor(messageName)
62 {
63 this.value = undefined;
64 this.add = function(response)
62 { 65 {
63 if (typeof response == "undefined") 66 if (typeof response == "undefined")
64 continue; 67 return;
65 68
66 if (typeof result == "undefined") 69 if (typeof this.value == "undefined")
67 result = response; 70 this.value = response;
68 else 71 else
69 Cu.reportError("Got multiple responses to message '" + messageName + "', o nly first response was accepted."); 72 Cu.reportError("Got multiple responses to message '" + messageName + "', o nly first response was accepted.");
70 } 73 };
71 return result;
72 } 74 }
73 75
74 function getSender(origin) 76 function getSender(origin)
75 { 77 {
76 if (origin instanceof Ci.nsIDOMXULElement) 78 if (origin instanceof Ci.nsIDOMXULElement)
77 origin = origin.messageManager; 79 origin = origin.messageManager;
78 80
79 if (origin instanceof Ci.nsIMessageSender) 81 if (origin instanceof Ci.nsIMessageSender)
80 return new LightWeightPort(origin); 82 return new LightWeightPort(origin);
81 else 83 else
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 } 176 }
175 else 177 else
176 this._sendResponse(sender, callbackID, result); 178 this._sendResponse(sender, callbackID, result);
177 179
178 return result; 180 return result;
179 }, 181 },
180 182
181 _handleResponse: function(message) 183 _handleResponse: function(message)
182 { 184 {
183 let {callbackID, payload} = message.data; 185 let {callbackID, payload} = message.data;
184 if (!this._responseCallbacks.has(callbackID)) 186 let callbackData = this._responseCallbacks.get(callbackID);
187 if (!callbackData)
185 return; 188 return;
186 189
187 let [callback, messageName, responses, expectedResponses] = 190 let [callback, processor, expectedResponses] = callbackData;
188 this._responseCallbacks.get(callbackID); 191
189 responses.push(payload); 192 try
190 if (responses.length == expectedResponses) 193 {
194 processor.add(payload);
195 }
196 catch (e)
197 {
198 Cu.reportError(e);
199 }
200
201 callbackData[2] = --expectedResponses;
202 if (expectedResponses <= 0)
191 { 203 {
192 this._responseCallbacks.delete(callbackID); 204 this._responseCallbacks.delete(callbackID);
193 callback(flattenResponses(responses, messageName)); 205 callback(processor.value);
194 } 206 }
195 }, 207 },
196 208
197 _dispatch: function(messageName, payload, sender) 209 _dispatch: function(messageName, payload, sender)
198 { 210 {
199 let callbacks = this._callbacks.get(messageName); 211 let callbacks = this._callbacks.get(messageName);
200 if (!callbacks) 212 if (!callbacks)
201 return undefined; 213 return undefined;
202 214
203 callbacks = callbacks.slice(); 215 callbacks = callbacks.slice();
204 let responses = []; 216 let processor = new ResponseProcessor(messageName);
205 for (let callback of callbacks) 217 for (let callback of callbacks)
206 { 218 {
207 try 219 try
208 { 220 {
209 responses.push(callback(payload, sender)); 221 processor.add(callback(payload, sender));
210 } 222 }
211 catch (e) 223 catch (e)
212 { 224 {
213 Cu.reportError(e); 225 Cu.reportError(e);
214 } 226 }
215 } 227 }
216 return flattenResponses(responses, messageName); 228 return processor.value;
217 }, 229 },
218 230
219 /** 231 /**
220 * Function to be called when a particular message is received 232 * Function to be called when a particular message is received
221 * @callback Port~messageHandler 233 * @callback Port~messageHandler
222 * @param payload data attached to the message if any 234 * @param payload data attached to the message if any
223 * @param {LightWeightPort} sender object that can be used to communicate with 235 * @param {LightWeightPort} sender object that can be used to communicate with
224 * the sender of the message, could be null 236 * the sender of the message, could be null
225 * @return the handler can return undefined (no response), a value (response 237 * @return the handler can return undefined (no response), a value (response
226 * to be sent to sender immediately) or a promise (asynchronous 238 * to be sent to sender immediately) or a promise (asynchronous
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 * @return {Promise} promise that will be resolved with the response 286 * @return {Promise} promise that will be resolved with the response
275 */ 287 */
276 emitWithResponse: function(messageName, payload) 288 emitWithResponse: function(messageName, payload)
277 { 289 {
278 let callbackID = ++this._responseCallbackCounter; 290 let callbackID = ++this._responseCallbackCounter;
279 let expectedResponses = sendMessage( 291 let expectedResponses = sendMessage(
280 this._messageManager, messageName, payload, callbackID); 292 this._messageManager, messageName, payload, callbackID);
281 return new Promise((resolve, reject) => 293 return new Promise((resolve, reject) =>
282 { 294 {
283 this._responseCallbacks.set(callbackID, 295 this._responseCallbacks.set(callbackID,
284 [resolve, messageName, [], expectedResponses]); 296 [resolve, new ResponseProcessor(messageName), expectedResponses]);
285 }); 297 });
286 }, 298 },
287 299
288 /** 300 /**
289 * Sends a synchonous message (DO NOT USE unless absolutely unavoidable). 301 * Sends a synchonous message (DO NOT USE unless absolutely unavoidable).
290 * @param {string} messageName message identifier 302 * @param {string} messageName message identifier
291 * @param [payload] data to attach to the message 303 * @param [payload] data to attach to the message
292 * @return response returned by the handler 304 * @return response returned by the handler
293 */ 305 */
294 emitSync: function(messageName, payload) 306 emitSync: function(messageName, payload)
(...skipping 12 matching lines...) Expand all
307 catch (e) 319 catch (e)
308 { 320 {
309 // Parent 321 // Parent
310 messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"] 322 messageManager = Cc["@mozilla.org/parentprocessmessagemanager;1"]
311 .getService(Ci.nsIMessageListenerManager); 323 .getService(Ci.nsIMessageListenerManager);
312 } 324 }
313 325
314 let port = new Port(messageManager); 326 let port = new Port(messageManager);
315 onShutdown.add(() => port.disconnect()); 327 onShutdown.add(() => port.disconnect());
316 exports.port = port; 328 exports.port = port;
LEFTRIGHT

Powered by Google App Engine
This is Rietveld