Spaces:
Running
Running
| /** | |
| * @author Deepkolos / https://github.com/deepkolos | |
| */ | |
| export class WorkerPool { | |
| constructor( pool = 4 ) { | |
| this.pool = pool; | |
| this.queue = []; | |
| this.workers = []; | |
| this.workersResolve = []; | |
| this.workerStatus = 0; | |
| } | |
| _initWorker( workerId ) { | |
| if ( ! this.workers[ workerId ] ) { | |
| const worker = this.workerCreator(); | |
| worker.addEventListener( 'message', this._onMessage.bind( this, workerId ) ); | |
| this.workers[ workerId ] = worker; | |
| } | |
| } | |
| _getIdleWorker() { | |
| for ( let i = 0; i < this.pool; i ++ ) | |
| if ( ! ( this.workerStatus & ( 1 << i ) ) ) return i; | |
| return - 1; | |
| } | |
| _onMessage( workerId, msg ) { | |
| const resolve = this.workersResolve[ workerId ]; | |
| resolve && resolve( msg ); | |
| if ( this.queue.length ) { | |
| const { resolve, msg, transfer } = this.queue.shift(); | |
| this.workersResolve[ workerId ] = resolve; | |
| this.workers[ workerId ].postMessage( msg, transfer ); | |
| } else { | |
| this.workerStatus ^= 1 << workerId; | |
| } | |
| } | |
| setWorkerCreator( workerCreator ) { | |
| this.workerCreator = workerCreator; | |
| } | |
| setWorkerLimit( pool ) { | |
| this.pool = pool; | |
| } | |
| postMessage( msg, transfer ) { | |
| return new Promise( ( resolve ) => { | |
| const workerId = this._getIdleWorker(); | |
| if ( workerId !== - 1 ) { | |
| this._initWorker( workerId ); | |
| this.workerStatus |= 1 << workerId; | |
| this.workersResolve[ workerId ] = resolve; | |
| this.workers[ workerId ].postMessage( msg, transfer ); | |
| } else { | |
| this.queue.push( { resolve, msg, transfer } ); | |
| } | |
| } ); | |
| } | |
| dispose() { | |
| this.workers.forEach( ( worker ) => worker.terminate() ); | |
| this.workersResolve.length = 0; | |
| this.workers.length = 0; | |
| this.queue.length = 0; | |
| this.workerStatus = 0; | |
| } | |
| } | |