Skip to content

Instantly share code, notes, and snippets.

@valentinkostadinov
Created January 15, 2013 09:29
Show Gist options
  • Save valentinkostadinov/4537501 to your computer and use it in GitHub Desktop.
Save valentinkostadinov/4537501 to your computer and use it in GitHub Desktop.
A simple HTML5 web worker pool (think thread pool) implementation for parallel execution of computationally intensive operations. The pool will lazily grow up to its given capacity. On saturation, messages will be queued up until a worker from the pool becomes available. The interface hides the Worker listener pattern and instead provides a sing…
/**
* A web worker pool implementation for parallel execution of
* computationally intensive operations. The pool will lazily grow up to its
* given capacity. On saturation, messages will be queued up until a worker
* from the pool becomes available.
*
* var capacity = 3;
* var pool = new WorkerPool(capacity, "./worker.js");
* for (var i = 0; i < 10; i++) {
* pool.postMessage(msg, function(err, result) {
*
* });
* }
*
* @param {number} capacity - The size of the pool. This will be the maximum
* concurrency allowed.
* @param {string} url - The web worker url. Workers are lazily created.
*
*/
function WorkerPool(capacity, url) {
this.capacity = capacity;
this.url = url;
this.queue = [];
this.idle = Array(capacity);
};
WorkerPool.prototype.postMessage = function(msg, callback) {
this.queue.push({
msg : msg,
callback : callback
});
this.dispatch();
};
WorkerPool.prototype.dispatch = function() {
if (!this.queue.length || !this.idle.length) {
return;
}
var task = this.queue.shift();
var worker = this.idle.pop() || new Worker(this.url);
var self = this;
function onEvent(e) {
this.removeEventListener('message', arguments.callee, false);
this.removeEventListener('error', arguments.callee, false);
self.idle.push(worker);
self.dispatch();
switch (e.type) {
case 'message':
task.callback.call(this, null, e.data, e);
break;
case 'error':
task.callback.call(this, e.message, null, e);
break;
}
};
worker.addEventListener('message', onEvent, false);
worker.addEventListener('error', onEvent, false);
worker.postMessage(task.msg);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment