Skip to content

Instantly share code, notes, and snippets.

@developit
Last active January 5, 2024 15:49
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save developit/65a2212731f6b00a8aaa55d70c594f5c to your computer and use it in GitHub Desktop.
Save developit/65a2212731f6b00a8aaa55d70c594f5c to your computer and use it in GitHub Desktop.
Simple pooling for workerize / workerize-loader.
/**
* 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();
});
}
}
@gpolyn
Copy link

gpolyn commented May 19, 2018

Change line 33 from
  return (...args) => self._queueJob(name, args)
to
  return (...args) => this._queueJob(name, args)

@developit
Copy link
Author

Whoops - good catch! I've updated it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment