| 
					
				 | 
			
			
				@@ -0,0 +1,52 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+from carrot.connection import DjangoAMQPConnection 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+from celery.utils import chunks 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def even_time_distribution(task, size, time_window, iterable, **apply_kwargs): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """With an iterator yielding task args, kwargs tuples, evenly distribute 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    the processing of its tasks throughout the time window available. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    :param task: The kind of task (a :class:`celery.task.base.Task`.) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    :param size: Total number of elements the iterator gives. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    :param time_window: Total time available, in minutes. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    :param iterable: Iterable yielding task args, kwargs tuples. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    :param \*\*apply_kwargs: Additional keyword arguments to be passed on to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        :func:`celery.execute.apply_async`. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Example 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        >>> class RefreshAllFeeds(Task): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ...     def run(self, **kwargs): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ...         feeds = Feed.objects.all() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ...         total = feeds.count() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ...         time_window = REFRESH_FEEDS_EVERY_INTERVAL_MINUTES 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ...         def iter_feed_task_args(iterable): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ...             for feed in iterable: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ...                 yield ([feed.feed_url], {}) # args, kwargs tuple 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ...         it = iter_feed_task_args(feeds.iterator()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ...         even_time_distribution(RefreshFeedTask, total, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ...                                time_window, it) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bucketsize = size / time_window 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    buckets = chunks(iterable, int(bucketsize)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    connection = DjangoAMQPConnection() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for bucket_count, bucket in enumerate(buckets): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # Skew the countdown for items in this bucket by one. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            seconds_eta = (60 * bucket_count if bucket_count else None) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for args, kwargs in bucket: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                task.apply_async(args=args, kwargs=kwargs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 connection=connection, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 countdown=seconds_eta, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 **apply_kwargs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    finally: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        connection.close() 
			 |