Skip to content

Instantly share code, notes, and snippets.

@gpolyn
Created May 19, 2018 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gpolyn/9a2ced1e6f4f12375f7430cfcc2ba6b6 to your computer and use it in GitHub Desktop.
Save gpolyn/9a2ced1e6f4f12375f7430cfcc2ba6b6 to your computer and use it in GitHub Desktop.
/**
* Copyright 2018 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* import Worker from 'workerize-loader!./worker';
* import WorkerPool from './worker-pool';
* let pool = new WorkerPool(Worker, 4);
* for (let i=10; i--; ) pool.doThing();
*/
export default (workerFactory, size) => new WorkerPool(workerFactory, size);
class WorkerPool {
constructor(workerFactory, size) {
let worker = (this.workerFactory = workerFactory)();
this.poolSize = size || 4;
this.used = 1;
this.pool = [worker];
this.jobs = [];
for (let i in worker) if (worker.hasOwnProperty(i) && typeof worker[i]==='function') {
this[i] = this._method(i); // proxy all methods available on the worker
}
}
_method(name) {
return (...args) => this._queueJob(name, args);
}
_queueJob(method, args) {
return new Promise((y, n) => {
this.jobs.push({ method, args, y, n });
this._nextJob();
})
}
_nextJob() {
let worker = this.pool.pop();
if (!worker) {
if (this.used >= this.poolSize) return;
this.used++;
worker = this.workerFactory();
}
const job = this.jobs.shift();
if (!job) return;
worker[job.method](...job.args).then(job.y).catch(job.n).finally(() => {
this.pool.push(worker);
this._nextJob();
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment