Merge pull request #309 from nasa/open308

[Workers] Allow web workers to be shared
This commit is contained in:
Victor Woeltjen
2015-11-20 11:40:26 -08:00
3 changed files with 55 additions and 4 deletions

View File

@ -1254,6 +1254,22 @@ object, or the current view proxy.
* `all()`: Get an array of all objects in the selection state. Will include * `all()`: Get an array of all objects in the selection state. Will include
either or both of the view proxy and selected object. 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).
Default value is `false`.
# Directives # Directives
Open MCT Web defines several Angular directives that are intended for use both Open MCT Web defines several Angular directives that are intended for use both
@ -1849,6 +1865,14 @@ the TelemetrySeries itself, in that order.
* `getSeries(domainObject)`: Get the latest `TelemetrySeries` (as resulted from * `getSeries(domainObject)`: Get the latest `TelemetrySeries` (as resulted from
a previous `request(...)` call) available for this domain object. 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 # Models
Domain object models in Open MCT Web are JavaScript objects describing the Domain object models in Open MCT Web are JavaScript objects describing the

View File

@ -38,7 +38,8 @@ define(
* @constructor * @constructor
*/ */
function WorkerService($window, workers) { function WorkerService($window, workers) {
var workerUrls = {}; var workerUrls = {},
sharedWorkers = {};
function addWorker(worker) { function addWorker(worker) {
var key = worker.key; var key = worker.key;
@ -48,12 +49,15 @@ define(
worker.bundle.sources, worker.bundle.sources,
worker.scriptUrl worker.scriptUrl
].join("/"); ].join("/");
sharedWorkers[key] = worker.shared;
} }
} }
(workers || []).forEach(addWorker); (workers || []).forEach(addWorker);
this.workerUrls = workerUrls; this.workerUrls = workerUrls;
this.sharedWorkers = sharedWorkers;
this.Worker = $window.Worker; this.Worker = $window.Worker;
this.SharedWorker = $window.SharedWorker;
} }
/** /**
@ -61,12 +65,17 @@ define(
* that has been registered under the `workers` category * that has been registered under the `workers` category
* of extension. * of extension.
* *
* This will return either a Worker or a SharedWorker,
* depending on whether a `shared` flag has been specified
* on the the extension definition for the referenced worker.
*
* @param {string} key symbolic identifier for the worker * @param {string} key symbolic identifier for the worker
* @returns {Worker} the running Worker * @returns {Worker | SharedWorker} the running Worker
*/ */
WorkerService.prototype.run = function (key) { WorkerService.prototype.run = function (key) {
var scriptUrl = this.workerUrls[key], var scriptUrl = this.workerUrls[key],
Worker = this.Worker; Worker = this.sharedWorkers[key] ?
this.SharedWorker : this.Worker;
return scriptUrl && Worker && new Worker(scriptUrl); return scriptUrl && Worker && new Worker(scriptUrl);
}; };

View File

@ -30,10 +30,14 @@ define(
var mockWindow, var mockWindow,
testWorkers, testWorkers,
mockWorker, mockWorker,
mockSharedWorker,
service; service;
beforeEach(function () { beforeEach(function () {
mockWindow = jasmine.createSpyObj('$window', ['Worker']); mockWindow = jasmine.createSpyObj(
'$window',
['Worker', 'SharedWorker']
);
testWorkers = [ testWorkers = [
{ {
key: 'abc', key: 'abc',
@ -49,11 +53,19 @@ define(
key: 'xyz', key: 'xyz',
scriptUrl: 'bad.js', scriptUrl: 'bad.js',
bundle: { path: 'bad', sources: 'bad' } bundle: { path: 'bad', sources: 'bad' }
},
{
key: 'a-shared-worker',
shared: true,
scriptUrl: 'c.js',
bundle: { path: 'a', sources: 'b' }
} }
]; ];
mockWorker = {}; mockWorker = {};
mockSharedWorker = {};
mockWindow.Worker.andReturn(mockWorker); mockWindow.Worker.andReturn(mockWorker);
mockWindow.SharedWorker.andReturn(mockSharedWorker);
service = new WorkerService(mockWindow, testWorkers); service = new WorkerService(mockWindow, testWorkers);
}); });
@ -68,6 +80,12 @@ define(
expect(mockWindow.Worker).toHaveBeenCalledWith('x/y/z.js'); 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 () { it("returns undefined for unknown workers", function () {
expect(service.run('def')).toBeUndefined(); expect(service.run('def')).toBeUndefined();
}); });