@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
134 lines (100 loc) • 2.75 kB
JavaScript
import { assert } from "../../assert.js";
export class OnDemandWorkerManager {
/**
* Number of active pending requests
* @type {number}
* @private
*/
__request_count = 0;
/**
* How long to wait before terminating the worker after it becomes idle
* in milliseconds
* @type {number}
* @private
*/
__timeout = 1000;
/**
* ID of the timer set via setTimeout
* @type {number}
* @private
*/
__pending_termination = -1;
/**
*
* @param {WorkerProxy} worker
*/
constructor(worker) {
/**
* @type {WorkerProxy}
*/
this.worker = worker;
}
/**
* Configure how long to wait after processing a request until deciding to shut down the worker
* @param {number} delay_ms In milliseconds
*/
setTimeout(delay_ms) {
assert.isNonNegativeInteger(delay_ms, 'v');
this.__timeout = delay_ms;
}
/**
* @private
*/
terminate = () => {
this.cancelScheduledTermination();
this.worker.stop();
}
/**
* @private
*/
cancelScheduledTermination() {
if (this.__pending_termination >= 0) {
clearInterval(this.__pending_termination);
this.__pending_termination = -1;
}
}
/**
*
* @param {number} timeout
*/
scheduleTermination(timeout) {
this.cancelScheduledTermination();
this.__pending_termination = setTimeout(this.terminate, timeout);
}
/**
* @private
*/
decrement = () => {
this.__request_count--;
if (this.__request_count <= 0 && this.worker.isRunning()) {
this.scheduleTermination(this.__timeout);
}
}
/**
* @private
*/
increment() {
this.__request_count++;
if (!this.worker.isRunning()) {
// worker is down, start it
this.worker.start();
} else if (this.__pending_termination >= 0) {
// worker is up, but we're in the termination timeout period, lets clear that
clearInterval(this.__pending_termination);
this.__pending_termination = -1;
}
}
/**
* Submit request to the worker
* @template T
* @param {string} name
* @param {Array} [parameters]
* @return {Promise<T>}
*/
request(name, parameters) {
this.increment();
const promise = this.worker.$submitRequest(name, parameters);
promise.finally(this.decrement);
return promise;
}
}