|  | @@ -5,8 +5,12 @@ Asynchronous result types.
 | 
	
		
			
				|  |  |  """
 | 
	
		
			
				|  |  |  from celery.backends import default_backend
 | 
	
		
			
				|  |  |  from celery.datastructures import PositionQueue
 | 
	
		
			
				|  |  | -from celery.timer import TimeoutTimer
 | 
	
		
			
				|  |  |  from itertools import imap
 | 
	
		
			
				|  |  | +import threading
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +class TimeoutError(Exception):
 | 
	
		
			
				|  |  | +    """The operation timed out."""
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  class BaseAsyncResult(object):
 | 
	
	
		
			
				|  | @@ -28,6 +32,8 @@ class BaseAsyncResult(object):
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      """
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    TimeoutError = TimeoutError
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def __init__(self, task_id, backend):
 | 
	
		
			
				|  |  |          self.task_id = task_id
 | 
	
		
			
				|  |  |          self.backend = backend
 | 
	
	
		
			
				|  | @@ -50,7 +56,7 @@ class BaseAsyncResult(object):
 | 
	
		
			
				|  |  |          :keyword timeout: How long to wait in seconds, before the
 | 
	
		
			
				|  |  |              operation times out.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        :raises celery.timer.TimeoutError: if ``timeout`` is not ``None`` and
 | 
	
		
			
				|  |  | +        :raises TimeoutError: if ``timeout`` is not ``None`` and
 | 
	
		
			
				|  |  |              the result does not arrive within ``timeout`` seconds.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          If the remote call raised an exception then that
 | 
	
	
		
			
				|  | @@ -253,7 +259,7 @@ class TaskSetResult(object):
 | 
	
		
			
				|  |  |          :keyword timeout: The time in seconds, how long
 | 
	
		
			
				|  |  |              it will wait for results, before the operation times out.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        :raises celery.timer.TimeoutError: if ``timeout`` is not ``None``
 | 
	
		
			
				|  |  | +        :raises TimeoutError: if ``timeout`` is not ``None``
 | 
	
		
			
				|  |  |              and the operation takes longer than ``timeout`` seconds.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          If any of the tasks raises an exception, the exception
 | 
	
	
		
			
				|  | @@ -262,23 +268,28 @@ class TaskSetResult(object):
 | 
	
		
			
				|  |  |          :returns: list of return values for all tasks in the taskset.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          """
 | 
	
		
			
				|  |  | -        timeout_timer = TimeoutTimer(timeout)
 | 
	
		
			
				|  |  | -        results = PositionQueue(length=self.total)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        while True:
 | 
	
		
			
				|  |  | -            for position, pending_result in enumerate(self.subtasks):
 | 
	
		
			
				|  |  | -                if pending_result.status == "DONE":
 | 
	
		
			
				|  |  | -                    results[position] = pending_result.result
 | 
	
		
			
				|  |  | -                elif pending_result.status == "FAILURE":
 | 
	
		
			
				|  |  | -                    raise pending_result.result
 | 
	
		
			
				|  |  | -            if results.full():
 | 
	
		
			
				|  |  | -                # Make list copy, so the returned type is not a position
 | 
	
		
			
				|  |  | -                # queue.
 | 
	
		
			
				|  |  | -                return list(results)
 | 
	
		
			
				|  |  | +        def on_timeout():
 | 
	
		
			
				|  |  | +            raise TimeoutError("The operation timed out.")
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            # This raises TimeoutError when timed out.
 | 
	
		
			
				|  |  | -            timeout_timer.tick()
 | 
	
		
			
				|  |  | +        timeout_timer = threading.Timer(timeout, on_timeout)
 | 
	
		
			
				|  |  | +        results = PositionQueue(length=self.total)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        timeout_timer.start()
 | 
	
		
			
				|  |  | +        try:
 | 
	
		
			
				|  |  | +            while True:
 | 
	
		
			
				|  |  | +                for position, pending_result in enumerate(self.subtasks):
 | 
	
		
			
				|  |  | +                    if pending_result.status == "DONE":
 | 
	
		
			
				|  |  | +                        results[position] = pending_result.result
 | 
	
		
			
				|  |  | +                    elif pending_result.status == "FAILURE":
 | 
	
		
			
				|  |  | +                        raise pending_result.result
 | 
	
		
			
				|  |  | +                if results.full():
 | 
	
		
			
				|  |  | +                    # Make list copy, so the returned type is not a position
 | 
	
		
			
				|  |  | +                    # queue.
 | 
	
		
			
				|  |  | +                    return list(results)
 | 
	
		
			
				|  |  | +        finally:
 | 
	
		
			
				|  |  | +            timeout_timer.cancel()
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  |      @property
 | 
	
		
			
				|  |  |      def total(self):
 | 
	
		
			
				|  |  |          """The total number of tasks in the :class:`celery.task.TaskSet`."""
 |