Created
January 15, 2013 09:29
-
-
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…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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