[Workers] Allow web workers to be shared

Support an additional flag in the  extension category
such that SharedWorkers may be used. nasa/openmctweb#308.
This commit is contained in:
Victor Woeltjen 2015-11-16 15:09:50 -08:00
parent 2b2ac0b0d9
commit 8363302caf
3 changed files with 49 additions and 3 deletions

View File

@ -1254,6 +1254,21 @@ 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).
# 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 +1864,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;
} }
/** /**
@ -66,7 +70,8 @@ define(
*/ */
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();
}); });