| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | *  | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | **********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | define(function(require){ var module = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //var DEBUG = DEBUG != null ? DEBUG : true
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var actions = require('lib/actions') | 
					
						
							| 
									
										
										
										
											2015-12-08 07:42:07 +03:00
										 |  |  | var object = require('lib/object') | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-27 05:22:17 +03:00
										 |  |  | // XXX need a mechanism to either queue chains of tasks that depend on 
 | 
					
						
							|  |  |  | // 		on the previous results or a way to delay a task until what it
 | 
					
						
							|  |  |  | // 		needs is finished...
 | 
					
						
							| 
									
										
										
										
											2016-04-18 17:27:34 +03:00
										 |  |  | // XXX add fatal .abort(..) of queue...
 | 
					
						
							| 
									
										
										
										
											2015-12-08 07:42:07 +03:00
										 |  |  | var QueueActions =  | 
					
						
							|  |  |  | module.QueueActions = actions.Actions({ | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 	config: { | 
					
						
							|  |  |  | 		'running-pool-size': 8, | 
					
						
							|  |  |  | 		// XXX at this point these is ignored...
 | 
					
						
							|  |  |  | 		'retry-limit': 5, | 
					
						
							|  |  |  | 		'default-queue-mode': 'resumable', | 
					
						
							| 
									
										
										
										
											2016-04-20 16:17:12 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		'clear-on-done': true, | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 	}, | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 	// NOTE: these are sparse...
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 	__ready: null, | 
					
						
							|  |  |  | 	__running: null, | 
					
						
							|  |  |  | 	__done: null, | 
					
						
							|  |  |  | 	__failed: null, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	get length(){ | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 		var that = this | 
					
						
							|  |  |  | 		//return ['__ready', '__running', '__done', '__failed']
 | 
					
						
							|  |  |  | 		return ['__ready', '__running'] | 
					
						
							|  |  |  | 			.reduce(function(a, b){ | 
					
						
							|  |  |  | 				return (typeof(a) == typeof(1) ? a  | 
					
						
							|  |  |  | 						: that[a] ? that[a].len  | 
					
						
							|  |  |  | 						: 0) | 
					
						
							|  |  |  | 					+ (typeof(b) == typeof(1) ? b  | 
					
						
							|  |  |  | 						: that[b] ? that[b].len  | 
					
						
							|  |  |  | 						: 0)  | 
					
						
							|  |  |  | 			}, 0) | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 	}, | 
					
						
							|  |  |  | 	set length(val){}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// can be:
 | 
					
						
							| 
									
										
										
										
											2016-04-20 03:56:19 +03:00
										 |  |  | 	// 	- stopped 	- (initial)
 | 
					
						
							|  |  |  | 	// 	- ready		- right after .start()
 | 
					
						
							|  |  |  | 	// 	- running	- while tasks are running
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// 									   +-------<done>--------+
 | 
					
						
							|  |  |  | 	// 									   v					 |
 | 
					
						
							|  |  |  | 	// 		o---> stopped ---(start)---> ready --+--> running ---+
 | 
					
						
							|  |  |  | 	// 				^							 |				 |
 | 
					
						
							|  |  |  | 	// 				+--------(stop)--------------+---------------+
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: while .start() and .stop() are both actions and events, 
 | 
					
						
							|  |  |  | 	// 		.done() is not an action, so it is not recommended to call 
 | 
					
						
							|  |  |  | 	// 		it manually...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 	// XXX should be more informative -- now supports only 'running' and 'stopped'
 | 
					
						
							|  |  |  | 	get state(){ | 
					
						
							|  |  |  | 		return this._state || 'stopped' | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 08:51:51 +03:00
										 |  |  | 	// General task life cycle events...
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 	// NOTE: these are not intended to be called by the user...
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 	// NOTE: .on('taskQueued') is just a more uniform shorthand for
 | 
					
						
							|  |  |  | 	// 		.on('enqueue') with one subtle difference, the former does
 | 
					
						
							|  |  |  | 	// 		not "wrap" the .enqueue(..) method with .pre/.post sub events
 | 
					
						
							|  |  |  | 	// 		and runs atomic as all other task events.
 | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 	taskQueued: ['', function(){}], | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 	// NOTE: binding to this is not the same as to .unqueue(..), this will
 | 
					
						
							|  |  |  | 	// 		get triggered once per each task deleted and not per method 
 | 
					
						
							|  |  |  | 	// 		call...
 | 
					
						
							|  |  |  | 	taskDropped: ['', function(){}], | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 	taskStarted: ['', function(){}], | 
					
						
							|  |  |  | 	taskFailed: ['', function(){}], | 
					
						
							|  |  |  | 	taskDone: ['', function(){}], | 
					
						
							| 
									
										
										
										
											2016-04-20 03:56:19 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-11 05:00:40 +03:00
										 |  |  | 	done: ['', function(func){ | 
					
						
							|  |  |  | 		func && this.on('done', func) }], | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 08:51:51 +03:00
										 |  |  | 	// Task manipulation actions...
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 	//
 | 
					
						
							|  |  |  | 	// A task can be either a Promise/A+ or a function. In the case of 
 | 
					
						
							|  |  |  | 	// a function this will work sync.
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | 	// NOTE: these and task events are partly redundant....
 | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 	enqueue: ['', | 
					
						
							|  |  |  | 		function(a, b, c){ | 
					
						
							|  |  |  | 			// normalize arguments...
 | 
					
						
							|  |  |  | 			if(typeof(a) == typeof('str')){ | 
					
						
							|  |  |  | 				var tag = a | 
					
						
							|  |  |  | 				var task = b | 
					
						
							|  |  |  | 				var mode = c | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				var tag = null | 
					
						
							|  |  |  | 				var task = a | 
					
						
							|  |  |  | 				var mode = b | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			mode = mode || this.config['default-queue-mode'] | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 			var ready = this.__ready = this.__ready || [] | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			ready.push([tag, task, mode]) | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 			this.taskQueued(tag, task, mode) | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// restart in case the queue was depleted...
 | 
					
						
							|  |  |  | 			this._run() | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 	unqueue: ['', | 
					
						
							|  |  |  | 		function(a, b){ | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 			var that = this | 
					
						
							|  |  |  | 			var ready = this.__ready | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 			// empty queue...
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 			if(ready == null || ready.len == 0){ | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// special case -- drop all...
 | 
					
						
							|  |  |  | 			if(a == '*'){ | 
					
						
							|  |  |  | 				ready.splice(0, ready.length) | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// XXX prep args...
 | 
					
						
							|  |  |  | 			var tag = typeof(a) == typeof('str') ? a : b | 
					
						
							|  |  |  | 			var task = typeof(a) == typeof('str') ? b : a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// no args...
 | 
					
						
							|  |  |  | 			if(tag == null && task == null){ | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// remove matching tasks from the queue...
 | 
					
						
							|  |  |  | 			ready.forEach(function(e, i){ | 
					
						
							|  |  |  | 				// only tag given...
 | 
					
						
							|  |  |  | 				if(task == null ? e[0] == tag | 
					
						
							|  |  |  | 						// only task given...
 | 
					
						
							|  |  |  | 						: tag == null ? e[1] === task | 
					
						
							|  |  |  | 						// both task and tag given...
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 						: e[0] == tag && e[1] === task){ | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 					delete ready[i] | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 					that.taskDropped(e[0], e[1], e[2]) | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 	delay: ['', | 
					
						
							|  |  |  | 		function(a, b){ | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 			var ready = this.__ready | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 			// empty queue...
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 			if(ready == null || ready.len == 0){ | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// XXX prep args...
 | 
					
						
							|  |  |  | 			var tag = typeof(a) == typeof('str') ? a : b | 
					
						
							|  |  |  | 			var task = typeof(a) == typeof('str') ? b : a | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// no args...
 | 
					
						
							|  |  |  | 			if(tag == null && task == null){ | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var delayed = [] | 
					
						
							|  |  |  | 			// remove the matching tasks...
 | 
					
						
							|  |  |  | 			ready.forEach(function(e, i){ | 
					
						
							|  |  |  | 				// only tag given...
 | 
					
						
							|  |  |  | 				var res = (task == null ? e[0] == tag | 
					
						
							|  |  |  | 					// only task given...
 | 
					
						
							|  |  |  | 					: tag == null ? e[1] === task | 
					
						
							|  |  |  | 					// both task and tag given...
 | 
					
						
							|  |  |  | 					: e[0] != tag && e[1] === task) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if(res){ | 
					
						
							|  |  |  | 					delete ready[i] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					delayed.push(e) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// push delayed list to the end of the queue...
 | 
					
						
							|  |  |  | 			delayed.forEach(function(e){ | 
					
						
							|  |  |  | 				ready.push(e) | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// restart in case the queue was depleted...
 | 
					
						
							|  |  |  | 			this._run() | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Run the queue...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// This is not intended for direct use...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// This can run in one of two ways:
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 	// 	1) run until the .__ready queue is completely depleted
 | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 	// 		This can occur for very fast or sync tasks, essentially
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 	// 		each iteration will replenish the .__running pool until there
 | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | 	// 		are no tasks to run.
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 	// 	2) load the .__running pool and exit
 | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 	// 		The first task to finish will run this again to replenish
 | 
					
						
							|  |  |  | 	// 		the pool.
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2015-12-26 23:21:14 +03:00
										 |  |  | 	// NOTE: there can be no more than one instance running at a time.
 | 
					
						
							| 
									
										
										
										
											2016-04-20 16:17:12 +03:00
										 |  |  | 	// NOTE: if .state is not 'running' or 'ready' this will silently exit.
 | 
					
						
							|  |  |  | 	// NOTE: if .state is 'ready' this will set it to 'running' and when 
 | 
					
						
							|  |  |  | 	// 		queue is depleted the .state will get set back to 'ready'
 | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 	//
 | 
					
						
							|  |  |  | 	// XXX need to handle retries correctly, at this point all errors just
 | 
					
						
							|  |  |  | 	// 		drop to failed and retry counter is incremented, there is no
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 	// 		flow back to .__running
 | 
					
						
							|  |  |  | 	// XXX this shifts the .__ready, this may cause a race with .unqueue(..)
 | 
					
						
							|  |  |  | 	// 		and .delay(..)
 | 
					
						
							|  |  |  | 	// 		really do not like setting this up with a for in or .forEach(..)
 | 
					
						
							|  |  |  | 	// 		as they will really complicate continuous operation...
 | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 	_run: ['', | 
					
						
							|  |  |  | 		function(){ | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 			if(this.__is_running){ | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			var that = this | 
					
						
							|  |  |  | 			var size = this.config['running-pool-size']  | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 			this.__running = this.__running || [] | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			// NOTE: the function in the look here is to clock some 
 | 
					
						
							|  |  |  | 			// 		values in a closure for reuse in promise state 
 | 
					
						
							|  |  |  | 			// 		handlers...
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 			// NOTE: we are not using .forEach(..) here because we need 
 | 
					
						
							|  |  |  | 			// 		to stop at abstract places and to see the list live...
 | 
					
						
							|  |  |  | 			while(this.__ready && this.__ready.len > 0  | 
					
						
							| 
									
										
										
										
											2016-04-20 03:56:19 +03:00
										 |  |  | 					&& (this.state == 'running' || this.state == 'ready') | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 					&& (this.__running && this.__running.len || 0) < size){ (function(){ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// XXX this might race...
 | 
					
						
							|  |  |  | 				var elem = that.__ready.shift() | 
					
						
							|  |  |  | 				if(elem == null){ | 
					
						
							|  |  |  | 					return  | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				var task = elem[1] | 
					
						
							|  |  |  | 				that.__is_running = true | 
					
						
							| 
									
										
										
										
											2016-04-20 03:56:19 +03:00
										 |  |  | 				that._state = 'running' | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				that.__running.push(elem) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// start the task...
 | 
					
						
							| 
									
										
										
										
											2016-01-18 05:20:14 +03:00
										 |  |  | 				// XXX should we run a task in some specific context???
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 				that.taskStarted(elem[0], task) | 
					
						
							| 
									
										
										
										
											2016-04-20 03:56:19 +03:00
										 |  |  | 				res = task() | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				// Promise/A+
 | 
					
						
							|  |  |  | 				if(res && res.then){ | 
					
						
							|  |  |  | 					res | 
					
						
							|  |  |  | 						// retry or move to failed...
 | 
					
						
							|  |  |  | 						.catch(function(){ | 
					
						
							|  |  |  | 							// pop self of .__running
 | 
					
						
							|  |  |  | 							delete that.__running[that.__running.indexOf(elem)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							// push self to .__failed
 | 
					
						
							|  |  |  | 							var failed = that.__failed = that.__failed || [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							// increment retry count...
 | 
					
						
							|  |  |  | 							elem[3] = (elem[3] || 0) + 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							// XXX check task mode and re-queue if needed...
 | 
					
						
							|  |  |  | 							// XXX
 | 
					
						
							|  |  |  | 							failed.push(elem) | 
					
						
							|  |  |  | 							that.taskFailed(elem[0], task) | 
					
						
							| 
									
										
										
										
											2015-12-08 07:42:07 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							// run some more...
 | 
					
						
							|  |  |  | 							that._run() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							// queue empty...
 | 
					
						
							| 
									
										
										
										
											2016-04-20 03:56:19 +03:00
										 |  |  | 							if(that.__ready && that.__ready.len == 0 | 
					
						
							|  |  |  | 									&& that.__running && that.__running.len == 0){ | 
					
						
							|  |  |  | 								that._state = 'ready' | 
					
						
							|  |  |  | 								that.done() | 
					
						
							| 
									
										
										
										
											2016-04-20 16:17:12 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 								that.config['clear-on-done']  | 
					
						
							|  |  |  | 									&& that.clear() | 
					
						
							| 
									
										
										
										
											2015-12-08 07:42:07 +03:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 						}) | 
					
						
							|  |  |  | 						// push to done and ._run some more...
 | 
					
						
							|  |  |  | 						.then(function(){ | 
					
						
							|  |  |  | 							// pop self of .__running
 | 
					
						
							|  |  |  | 							delete that.__running[that.__running.indexOf(elem)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							// push self to .__done
 | 
					
						
							|  |  |  | 							var done = that.__done = that.__done || [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 							done.push(elem) | 
					
						
							| 
									
										
										
										
											2015-12-08 07:42:07 +03:00
										 |  |  | 							that.taskDone(elem[0], task) | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							// run some more...
 | 
					
						
							|  |  |  | 							that._run() | 
					
						
							| 
									
										
										
										
											2015-12-08 07:42:07 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							// queue empty...
 | 
					
						
							| 
									
										
										
										
											2016-04-20 03:56:19 +03:00
										 |  |  | 							if(that.__ready && that.__ready.len == 0 | 
					
						
							|  |  |  | 									&& that.__running && that.__running.len == 0){ | 
					
						
							|  |  |  | 								that._state = 'ready' | 
					
						
							|  |  |  | 								that.done() | 
					
						
							| 
									
										
										
										
											2016-04-20 16:17:12 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 								that.config['clear-on-done'] | 
					
						
							|  |  |  | 									&& that.clear() | 
					
						
							| 
									
										
										
										
											2015-12-08 07:42:07 +03:00
										 |  |  | 							} | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 						}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// other...
 | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					// pop self of .__running
 | 
					
						
							|  |  |  | 					delete that.__running[that.__running.indexOf(elem)] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					// push self to .__done
 | 
					
						
							|  |  |  | 					var done = that.__done = that.__done || [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					done.push(elem) | 
					
						
							|  |  |  | 					that.taskDone(elem[0], task) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 07:42:07 +03:00
										 |  |  | 					// queue empty...
 | 
					
						
							| 
									
										
										
										
											2016-04-20 03:56:19 +03:00
										 |  |  | 					if(that.__ready && that.__ready.len == 0 | 
					
						
							|  |  |  | 							&& that.__running && that.__running.len == 0){ | 
					
						
							|  |  |  | 						that._state = 'ready' | 
					
						
							|  |  |  | 						that.done() | 
					
						
							| 
									
										
										
										
											2016-04-20 16:17:12 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 						that.config['clear-on-done']  | 
					
						
							|  |  |  | 							&& that.clear() | 
					
						
							| 
									
										
										
										
											2015-12-08 07:42:07 +03:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 			})() } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 			delete that.__is_running | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 		}], | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 08:51:51 +03:00
										 |  |  | 	// State manipulation actions...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 	// NOTE: we do not need events for these as they are actions...
 | 
					
						
							|  |  |  | 	start: ['', | 
					
						
							|  |  |  | 		function(){ | 
					
						
							| 
									
										
										
										
											2016-04-20 03:56:19 +03:00
										 |  |  | 			this._state = 'ready' | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 			this._run() | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 	stop: ['', | 
					
						
							|  |  |  | 		function(){ | 
					
						
							|  |  |  | 			delete this._state | 
					
						
							|  |  |  | 		}], | 
					
						
							|  |  |  | 	clear: ['', | 
					
						
							|  |  |  | 		function(){ | 
					
						
							| 
									
										
										
										
											2016-04-20 16:17:12 +03:00
										 |  |  | 			// XXX should this stop???
 | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 			this.stop() | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 			delete this.__ready | 
					
						
							|  |  |  | 			delete this.__running | 
					
						
							|  |  |  | 			delete this.__failed | 
					
						
							|  |  |  | 			delete this.__done | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 		}], | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 07:42:07 +03:00
										 |  |  | var Queue =  | 
					
						
							|  |  |  | module.Queue =  | 
					
						
							|  |  |  | object.makeConstructor('Queue', QueueActions) | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 06:56:54 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 05:08:52 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | * vim:set ts=4 sw=4 :                                                */ | 
					
						
							|  |  |  | return module }) |