UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

140 lines (108 loc) 2.97 kB
import { assert } from "../../assert.js"; /** * Worker manager that will terminate the worker after a timeout if it is idle. * */ 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_ms = 1000; /** * ID of the timer set via setTimeout * @type {number} * @private */ __pending_termination = -1; /** * * @param {WorkerProxy} worker */ constructor(worker) { assert.defined(worker, 'worker'); /** * @type {WorkerProxy} */ this.worker = worker; } /** * Configure how long to wait after processing a request until deciding to shut down the worker. * The browser limits the number of workers we can have open at once, so releasing them when not in use is critical. * * @param {number} delay_ms In milliseconds */ setTimeout(delay_ms) { assert.isNonNegativeInteger(delay_ms, 'delay_ms'); this.__timeout_ms = delay_ms; } /** * @private */ terminate = () => { this.cancelScheduledTermination(); this.worker.stop(); } /** * @private */ cancelScheduledTermination() { if (this.__pending_termination < 0) { // no pending termination return; } 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_ms); } } /** * @private */ increment() { this.__request_count++; if (!this.worker.isRunning()) { // worker is down, start it this.worker.start(); } else { // worker is up, ensure we're not waiting for it to terminate this.cancelScheduledTermination(); } } /** * Submit a 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; } }