From 97d67d75f480e02bb92b42f82b0fd24cbd8ced48 Mon Sep 17 00:00:00 2001 From: Christopher Willis-Ford Date: Fri, 21 Jul 2017 13:13:45 -0700 Subject: [PATCH] Allow 'then' on service registration This allows a service to postpone communication with other services until it can be sure that it's registered with central dispatch. Service registration on the main thread always happens immediately, but that version of `setService` still returns a Promise for consistency. --- src/dispatch/central-dispatch.js | 22 +++++++++++++++------- src/dispatch/worker-dispatch.js | 7 +++---- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/dispatch/central-dispatch.js b/src/dispatch/central-dispatch.js index 9d1388724..98bb2805a 100644 --- a/src/dispatch/central-dispatch.js +++ b/src/dispatch/central-dispatch.js @@ -106,15 +106,19 @@ class CentralDispatch { /** * Set a local object as the global provider of the specified service. + * WARNING: Any method on the provider can be called from any worker within the dispatch system. * @param {string} service - a globally unique string identifying this service. Examples: 'vm', 'gui', 'extension9'. * @param {object} provider - a local object which provides this service. - * WARNING: Any method on the provider can be called from any worker within the dispatch system. + * @returns {Promise} - a promise which will resolve once the service is registered. */ setService (service, provider) { - if (this.services.hasOwnProperty(service)) { - log.warn(`Replacing existing service provider for ${service}`); - } - this.services[service] = provider; + return new Promise(resolve => { + if (this.services.hasOwnProperty(service)) { + log.warn(`Replacing existing service provider for ${service}`); + } + this.services[service] = provider; + resolve(); + }); } /** @@ -140,17 +144,21 @@ class CentralDispatch { */ _onMessage (worker, event) { const [service, method, callbackId, ...args] = /** @type {[string, string, *]} */ event.data; + let promise; if (service === 'dispatch') { switch (method) { case '_callback': this._callback(callbackId, ...args); break; case 'setService': - this.setService(args[0], worker); + promise = this.setService(args[0], worker); break; } } else { - this.call(service, method, ...args).then( + promise = this.call(service, method, ...args); + } + if (promise) { + promise.then( result => { worker.postMessage(['dispatch', '_callback', callbackId, result]); }, diff --git a/src/dispatch/worker-dispatch.js b/src/dispatch/worker-dispatch.js index a0127d067..50328d84c 100644 --- a/src/dispatch/worker-dispatch.js +++ b/src/dispatch/worker-dispatch.js @@ -117,18 +117,17 @@ class WorkerDispatch { /** * Set a local object as the global provider of the specified service. + * WARNING: Any method on the provider can be called from any worker within the dispatch system. * @param {string} service - a globally unique string identifying this service. Examples: 'vm', 'gui', 'extension9'. * @param {object} provider - a local object which provides this service. - * WARNING: Any method on the provider can be called from any worker within the dispatch system. + * @returns {Promise} - a promise which will resolve once the service is registered. */ setService (service, provider) { if (this.services.hasOwnProperty(service)) { log.warn(`Replacing existing service provider for ${service}`); } this.services[service] = provider; - this.waitForConnection.then(() => { - this.call('dispatch', 'setService', service); - }); + return this.waitForConnection.then(() => this.call('dispatch', 'setService', service)); } /**