Implements a shutdown() function on LMLayer, killing the worker.

This commit is contained in:
Joshua A. Horton 2019-03-04 09:01:34 +07:00
parent 3c086a8ef6
commit 320ac0901d
6 changed files with 24 additions and 0 deletions

View file

@ -113,6 +113,14 @@ namespace com.keyman.text.prediction {
}
}
/**
* Clears out any computational resources in use by the LMLayer, including shutting
* down any internal WebWorkers.
*/
public shutdown() {
this._worker.terminate();
}
/**
* Given a function, this utility returns the source code within it, as a string.
* This is intended to unwrap the "wrapped" source code created in the LMLayerWorker

View file

@ -6,6 +6,7 @@ describe('LMLayer', function () {
it('should construct with zero arguments', function () {
let lmLayer = new LMLayer();
assert.instanceOf(lmLayer, LMLayer);
lmLayer.shutdown();
});
});
@ -25,6 +26,7 @@ describe('LMLayer', function () {
let worker = new Worker(uri);
worker.onmessage = function thisShouldBeCalled(event) {
assert.propertyVal(event, 'data', 'fhqwhgads');
worker.terminate();
done();
};
})

View file

@ -35,6 +35,7 @@ describe('LMLayer using dummy model', function () {
return lmLayer.predict(zeroTransform(), emptyContext());
}).then(function (suggestions) {
assert.deepEqual(suggestions, iGotDistractedByHazel()[3]);
lmLayer.shutdown();
return Promise.resolve();
});
});

View file

@ -35,6 +35,7 @@ describe('LMLayer using the word list model', function () {
return lmLayer.predict(type('q'), atEndOfBuffer('the '));
}).then(function (suggestions) {
assert.isAtLeast(suggestions.length, EXPECTED_SUGGESTIONS);
lmLayer.shutdown();
return Promise.resolve();
});
});

View file

@ -17,6 +17,7 @@ describe('LMLayerWorker', function () {
let worker = new Worker(uri);
worker.onmessage = function thisShouldBeCalled(message) {
done();
worker.terminate();
};
worker.postMessage({
message: 'initialize',

View file

@ -72,6 +72,9 @@ class LMLayerWorker {
/**
* By default, it's self.importScripts(), but can be overridden
* so that this can be tested **outside of a Worker**.
*
* To function properly, self.importScripts() must be bound to self
* before being stored here, else it will fail.
*/
private _importScripts: ImportScripts;
@ -161,6 +164,13 @@ class LMLayerWorker {
this._importScripts(url);
}
public unloadModel() {
// Right now, this seems sufficient to clear out the old model.
// The only existing reference to a loaded model is held by
// transitionToReadyState's `handleMessage` closure. (The `model` var)
this.setupInitialState();
}
/**
* Sets the initial state, i.e., `uninitialized`.
* This state only handles `initialized` messages, and will
@ -229,6 +239,7 @@ class LMLayerWorker {
scope.onmessage = worker.onMessage.bind(worker);
// Ensures that the worker instance is accessible for loaded model scripts.
// Assists unit-testing.
scope['LMLayerWorker'] = worker;
scope['models'] = models;