Skip to content

Instantly share code, notes, and snippets.

@break24
Created September 5, 2014 15:25
Show Gist options
  • Save break24/a65391b504baac116eae to your computer and use it in GitHub Desktop.
Save break24/a65391b504baac116eae to your computer and use it in GitHub Desktop.
ThreadPool.js, a requirejs module for managing multiple webworkers,
define(function() {
// read more: http://www.smartjava.org/content/html5-easily-parallelize-jobs-using-web-workers-and-threadpool
var ThreadPool = function(size, isIdleCallback) {
// set some defaults
console.log("Init ThreadPool");
this.taskQueue = [];
this.workerQueue = [];
this.poolSize = size || 4;
this.isIdleCallback = isIdleCallback || function() {
};
};
ThreadPool.prototype.init = function() {
console.log("Init queues ");
for (var i = 1; i <= this.poolSize; i++) {
console.log("Init queue " + i);
this.workerQueue.push(new WorkerThread(this, i));
}
};
ThreadPool.prototype.addWorkerTask = function(scriptOrWorker, messageHandler, tid) {
var workerTask = new WorkerTask(scriptOrWorker, messageHandler, tid);
if (this.workerQueue.length > 0) {
console.log("Start new task");
// get the worker from the front of the queue
var workerThread = this.workerQueue.shift();
workerThread.run(workerTask);
} else {
// no free workers,
this.taskQueue.push(workerTask);
}
};
ThreadPool.prototype.isIdle = function() {
return this.workerQueue.length === this.poolSize;
};
ThreadPool.prototype.freeWorkerThread = function(workerThread) {
console.log("Free thread. ID: " + workerThread.id);
if (this.taskQueue.length > 0) {
var workerTask = this.taskQueue.shift();
workerThread.run(workerTask);
} else {
this.workerQueue.push(workerThread);
if (this.workerQueue.length === this.poolSize) {
this.isIdleCallback();
}
}
};
function WorkerThread(parentPool, id) {
this.parentPool = parentPool;
this.workerTask = {};
this.id = id;
this.worker = null;
this.run = function(workerTask) {
this.workerTask = workerTask;
// create a new web worker
if (this.workerTask.scriptOrWorker instanceof Worker) {
this.worker = this.workerTask.scriptOrWorker
} else {
this.worker = new Worker(workerTask.scriptOrWorker);
}
workerTask.callback(this);
};
WorkerThread.prototype.freeThread = function() {
console.log("Finish worker.");
this.worker.terminate();
this.parentPool.freeWorkerThread(this);
};
}
function WorkerTask(scriptOrWorker, callback, parallelCounter) {
this.scriptOrWorker = scriptOrWorker;
this.callback = callback;
this.id = parallelCounter;
}
return ThreadPool;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment