added docs...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2014-01-21 06:06:34 +04:00
parent c45405f608
commit 7cdf21c2e3
2 changed files with 121 additions and 33 deletions

View File

@ -848,7 +848,6 @@ function exportImagesTo(path, im_name, dir_name, size){
showStatusQ('Export: done.') showStatusQ('Export: done.')
res.resolve() res.resolve()
}) })
window.Pool = pool
// go through ribbons... // go through ribbons...
for(var i=DATA.ribbons.length-1; i >= 0; i--){ for(var i=DATA.ribbons.length-1; i >= 0; i--){

View File

@ -727,6 +727,47 @@ function makeDeferredsQ(first){
} }
// Deferred worker pool...
//
// This will create and return a pooled queue of deferred workers.
//
// Public interface:
//
// .enqueue(obj, func, args)
// Add a worker to queue.
// If the pool is empty this will run the worker right away.
// If the pool is full the worker is added to queue (FILO) and
// run as it's turn arrives.
//
// .dropQueue()
// Drop the queued workers.
// NOTE: this will not stop the already running workers.
//
// .progress(func)
// Register a progress handler.
// The handler is called after each worker is done and will get
// passed:
// - pool
// - workers done count
// - workers total count
// NOTE: the total number of workers can change as new workers
// are added or the queue is cleared...
//
// .fail(func)
// Register a worker fail handler.
// The handler is called when a worker goes into the fail state.
// This will get passed:
// - pool
// - workers done count
// - workers total count
// NOTE: this will not stop the execution of other handlers.
//
// .depleted(func)
// Register a depleted pool handler.
// The handler will get called when the queue and pool are empty
// (depleted) and the last worker is done.
//
//
// XXX should this be an object or a factory??? // XXX should this be an object or a factory???
function makeDefferedPool(size){ function makeDefferedPool(size){
size = size == null ? POOL_SIZE : size size = size == null ? POOL_SIZE : size
@ -736,16 +777,14 @@ function makeDefferedPool(size){
var Pool = { var Pool = {
pool: [], pool: [],
size: size,
queue: [], queue: [],
} size: size,
var len = function(){ _deplete_handlers: [],
return Pool.pool.filter(function(){ return true }).length _progress_handlers: [],
_fail_handlers: [],
} }
Pool._deplete_handlers = []
Pool._run = function(obj, func, args){ Pool._run = function(obj, func, args){
var that = this var that = this
var pool = this.pool var pool = this.pool
@ -759,39 +798,45 @@ function makeDefferedPool(size){
// prepare to remove self from pool... // prepare to remove self from pool...
var i = pool.indexOf(worker) var i = pool.indexOf(worker)
Pool._progress_handlers.forEach(function(func){
func(that, pool.length - pool.len(), pool.length + queue.length)
})
// remove self from queue...
delete pool[i]
// shrink the pool if it's overfilled... // shrink the pool if it's overfilled...
if(len(pool) > pool_size){ // i.e. do not pop another worker and let the "thread" die.
if(pool.len() > pool_size){
// remove self... // remove self...
delete pool[i]
return return
} }
// get the next queue item... // get the next queued worker...
var next = queue.splice(0, 1)[0] var next = queue.splice(0, 1)[0]
// run the next worker if it exists... // run the next worker if it exists...
if(next != null){ if(next != null){
// replace self with next worker...
run.apply(that, next) run.apply(that, next)
delete pool[i]
// nothing in queue... // empty queue AND empty pool mean we are done...
} else { } else if(pool.len() == 0){
// remove self... // NOTE: potential race condition -- something can be
delete pool[i] // pushed to pool just before it's "compacted"...
pool.length = 0
// empty queue AND empty pool mean we are done... that._deplete_handlers.forEach(function(func){
if(len(pool) == 0){ func(that)
that._deplete() })
}
} }
// keep the pool full... // keep the pool full...
that._fill() that._fill()
}) })
.fail(function(){ .fail(function(){
// XXX Pool._fail_handlers.forEach(function(func){
//queue.splice(0, queue.length) func(that, pool.length - pool.len(), pool.length + queue.length)
})
}) })
this.pool.push(worker) this.pool.push(worker)
@ -802,7 +847,7 @@ function makeDefferedPool(size){
var that = this var that = this
var pool_size = this.size var pool_size = this.size
var run = this._run var run = this._run
var l = len(this.pool) var l = this.pool.len()
if(l < pool_size && this.queue.length > 0){ if(l < pool_size && this.queue.length > 0){
this.queue.splice(0, pool_size - l) this.queue.splice(0, pool_size - l)
@ -813,15 +858,12 @@ function makeDefferedPool(size){
return this return this
} }
Pool._deplete = function(){
var that = this
this._deplete_handlers.forEach(function(func){
func(that)
})
return this
}
// public methods...
// Public methods...
// Add a worker to queue...
//
Pool.enqueue = function(obj, func, args){ Pool.enqueue = function(obj, func, args){
// add worker to queue... // add worker to queue...
this.queue.push([obj, func, args]) this.queue.push([obj, func, args])
@ -830,12 +872,53 @@ function makeDefferedPool(size){
this._fill() this._fill()
return this return this
} }
// This is called after the pool is populated and depleted...
// Drop the queued workers...
//
// NOTE: this will not stop the running workers...
Pool.dropQueue = function(){
this.queue.splice(0, this.queue.length)
}
// Register a queue depleted handler...
//
// This occurs when a populated queue is depleted and the last worker
// is done.
//
// NOTE: this is similar to jQuery.Deferred().done(..) but differs in
// that the pool can fill up and get depleted more than once,
// thus, the handlers may get called more than once per pool
// life...
// NOTE: it is recommended to fill the queue faster than the workers
// finish, as this may get called after last worker is done and
// the next is queued...
Pool.depleted = function(func){ Pool.depleted = function(func){
this._deplete_handlers.push(func) this._deplete_handlers.push(func)
return this return this
} }
// Register queue progress handler...
//
// This occurs after each worker is done.
//
// handler will be passed:
// - the pool object
// - workers done
// - total workers (done + queued)
Pool.progress = function(func){
this._progress_handlers.push(func)
return this
}
// Register worker fail handler...
//
Pool.fail = function(func){
this._fail_handlers.push(func)
return this
}
return Pool return Pool
} }
@ -896,6 +979,12 @@ Object.get = function(obj, name, dfl){
return val return val
} }
// like .length but for sparse arrays will return the element count...
Array.prototype.len = function(){
return this.filter(function(){ return true }).length
}
// convert JS arguments to Array... // convert JS arguments to Array...
function args2array(args){ function args2array(args){