From 8363302cafd79291fb574d4c6a53e4d9dc2833ce Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 16 Nov 2015 15:09:50 -0800 Subject: [PATCH] [Workers] Allow web workers to be shared Support an additional flag in the extension category such that SharedWorkers may be used. nasa/openmctweb#308. --- docs/src/guide/index.md | 23 ++++++++++++++++++++ platform/execution/src/WorkerService.js | 9 ++++++-- platform/execution/test/WorkerServiceSpec.js | 20 ++++++++++++++++- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/docs/src/guide/index.md b/docs/src/guide/index.md index a0159ec672..e84909d42b 100644 --- a/docs/src/guide/index.md +++ b/docs/src/guide/index.md @@ -1254,6 +1254,21 @@ object, or the current view proxy. * `all()`: Get an array of all objects in the selection state. Will include either or both of the view proxy and selected object. +## Workers Category + +The `workers` extension category allows scripts to be run as web workers +using the `workerService`. + +An extension of this category has no implementation. The following properties +are supported: + +* `key`: A symbolic string used to identify this worker. +* `workerUrl`: The path, relative to this bundle's `src` folder, where + this worker's source code resides. +* `shared`: Optional; a boolean flag which, if true, indicates that this + worker should be instantiated as a + [`SharedWorker`](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/SharedWorker). + # Directives Open MCT Web defines several Angular directives that are intended for use both @@ -1849,6 +1864,14 @@ the TelemetrySeries itself, in that order. * `getSeries(domainObject)`: Get the latest `TelemetrySeries` (as resulted from a previous `request(...)` call) available for this domain object. +### Worker Service + +The `workerService` may be used to run web workers defined via the +`workers` extension category. It has the following method: + +* `run(key)`: Run the worker identified by the provided `key`. Returns + a `Worker` (or `SharedWorker`, if the specified worker is defined + as a shared worker); if the `key` is unknown, returns `undefined`. # Models Domain object models in Open MCT Web are JavaScript objects describing the diff --git a/platform/execution/src/WorkerService.js b/platform/execution/src/WorkerService.js index 68eb171b0f..1e143301da 100644 --- a/platform/execution/src/WorkerService.js +++ b/platform/execution/src/WorkerService.js @@ -38,7 +38,8 @@ define( * @constructor */ function WorkerService($window, workers) { - var workerUrls = {}; + var workerUrls = {}, + sharedWorkers = {}; function addWorker(worker) { var key = worker.key; @@ -48,12 +49,15 @@ define( worker.bundle.sources, worker.scriptUrl ].join("/"); + sharedWorkers[key] = worker.shared; } } (workers || []).forEach(addWorker); this.workerUrls = workerUrls; + this.sharedWorkers = sharedWorkers; this.Worker = $window.Worker; + this.SharedWorker = $window.SharedWorker; } /** @@ -66,7 +70,8 @@ define( */ WorkerService.prototype.run = function (key) { var scriptUrl = this.workerUrls[key], - Worker = this.Worker; + Worker = this.sharedWorkers[key] ? + this.SharedWorker : this.Worker; return scriptUrl && Worker && new Worker(scriptUrl); }; diff --git a/platform/execution/test/WorkerServiceSpec.js b/platform/execution/test/WorkerServiceSpec.js index 24abab6e81..e1a287f60d 100644 --- a/platform/execution/test/WorkerServiceSpec.js +++ b/platform/execution/test/WorkerServiceSpec.js @@ -30,10 +30,14 @@ define( var mockWindow, testWorkers, mockWorker, + mockSharedWorker, service; beforeEach(function () { - mockWindow = jasmine.createSpyObj('$window', ['Worker']); + mockWindow = jasmine.createSpyObj( + '$window', + ['Worker', 'SharedWorker'] + ); testWorkers = [ { key: 'abc', @@ -49,11 +53,19 @@ define( key: 'xyz', scriptUrl: 'bad.js', bundle: { path: 'bad', sources: 'bad' } + }, + { + key: 'a-shared-worker', + shared: true, + scriptUrl: 'c.js', + bundle: { path: 'a', sources: 'b' } } ]; mockWorker = {}; + mockSharedWorker = {}; mockWindow.Worker.andReturn(mockWorker); + mockWindow.SharedWorker.andReturn(mockSharedWorker); service = new WorkerService(mockWindow, testWorkers); }); @@ -68,6 +80,12 @@ define( expect(mockWindow.Worker).toHaveBeenCalledWith('x/y/z.js'); }); + it("allows workers to be shared", function () { + expect(service.run('a-shared-worker')).toBe(mockSharedWorker); + expect(mockWindow.SharedWorker) + .toHaveBeenCalledWith('a/b/c.js'); + }); + it("returns undefined for unknown workers", function () { expect(service.run('def')).toBeUndefined(); });