| 
					
				 | 
			
			
				@@ -46,7 +46,8 @@ class subtask(AttributeDict): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    def __init__(self, task=None, args=None, kwargs=None, options=None, **ex): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def __init__(self, task=None, args=None, kwargs=None, options=None, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                type=None, **ex): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         init = super(subtask, self).__init__ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if isinstance(task, dict): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -55,6 +56,7 @@ class subtask(AttributeDict): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Also supports using task class/instance instead of string name. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             task_name = task.name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self._type = task 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         except AttributeError: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             task_name = task 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -117,7 +119,7 @@ class subtask(AttributeDict): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     @cached_property 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def type(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return current_app.tasks[self.task] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return self._type or current_app.tasks[self.task] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 def maybe_subtask(t): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -126,7 +128,7 @@ def maybe_subtask(t): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return t 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-class TaskSet(UserList): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class group(UserList): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     """A task containing several subtasks, making it possible 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     to track how many, or when all of the tasks have been completed. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -135,19 +137,16 @@ class TaskSet(UserList): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Example:: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         >>> urls = ("http://cnn.com/rss", "http://bbc.co.uk/rss") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        >>> taskset = TaskSet(refresh_feed.subtask((url, )) for url in urls) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        >>> taskset_result = taskset.apply_async() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        >>> list_of_return_values = taskset_result.join()  # *expensive* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> g = group(refresh_feed.subtask((url, )) for url in urls) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> group_result = g.apply_async() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> list_of_return_values = group_result.join()  # *expensive* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    #: Total number of subtasks in this set. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    total = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def __init__(self, tasks=None, app=None, Publisher=None): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        self.app = app_or_default(app) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self._app = app 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.data = [maybe_subtask(t) for t in tasks or []] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        self.total = len(self.tasks) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        self.Publisher = Publisher or self.app.amqp.TaskPublisher 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self._Publisher = Publisher 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def apply_async(self, connection=None, connect_timeout=None, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             publisher=None, taskset_id=None): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -184,10 +183,29 @@ class TaskSet(UserList): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def _sync_results(self, taskset_id): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return [task.apply(taskset_id=taskset_id) for task in self.tasks] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @property 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def total(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        """Number of subtasks in this group.""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return len(self) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def _get_app(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return self._app or self.data[0].type.app 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def _set_app(self, app): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self._app = app 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    app = property(_get_app, _set_app) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def _get_tasks(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return self.data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def _set_tasks(self, tasks): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.data = tasks 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     tasks = property(_get_tasks, _set_tasks) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-group = TaskSet 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def _get_Publisher(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return self._Publisher or self.app.amqp.TaskPublisher 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def _set_Publisher(self, Publisher): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self._Publisher = Publisher 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Publisher = property(_get_Publisher, _set_Publisher) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+TaskSet = group 
			 |