|  | @@ -77,22 +77,45 @@ class PeriodicTaskManager(models.Manager):
 | 
	
		
			
				|  |  |          row = cursor.fetchone()
 | 
	
		
			
				|  |  |          return row
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    def init_entries(self):
 | 
	
		
			
				|  |  | +        """Add entries for all registered periodic tasks.
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        Should be run at worker start.
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        periodic_tasks = tasks.get_all_periodic()
 | 
	
		
			
				|  |  | +        for task_name in periodic_tasks.keys():
 | 
	
		
			
				|  |  | +            task_meta, created = self.get_or_create(name=task_name)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def is_time(self, last_run_at, run_every):
 | 
	
		
			
				|  |  | +        run_every_drifted = run_every + SERVER_DRIFT
 | 
	
		
			
				|  |  | +        run_at = last_run_at + run_every_drifted
 | 
	
		
			
				|  |  | +        if datetime.now() > run_at:
 | 
	
		
			
				|  |  | +            return True
 | 
	
		
			
				|  |  | +        return False
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def get_waiting_tasks(self):
 | 
	
		
			
				|  |  |          """Get all waiting periodic tasks.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          :returns: list of :class:`celery.models.PeriodicTaskMeta` objects.
 | 
	
		
			
				|  |  |          """
 | 
	
		
			
				|  |  |          periodic_tasks = tasks.get_all_periodic()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        # Find all periodic tasks to be run.
 | 
	
		
			
				|  |  |          waiting = []
 | 
	
		
			
				|  |  | -        # XXX This will become a lot of queries. Maybe just only create
 | 
	
		
			
				|  |  | -        # the rows at init, and then select all later.
 | 
	
		
			
				|  |  | -        for task_name, task in periodic_tasks.items():
 | 
	
		
			
				|  |  | -            self.lock()
 | 
	
		
			
				|  |  | -            task_meta, created = self.get_or_create(name=task_name)
 | 
	
		
			
				|  |  | -            # task_run.every must be a timedelta object.
 | 
	
		
			
				|  |  | -            run_every_drifted = task.run_every + SERVER_DRIFT
 | 
	
		
			
				|  |  | -            run_at = task_meta.last_run_at + run_every_drifted
 | 
	
		
			
				|  |  | -            if datetime.now() > run_at:
 | 
	
		
			
				|  |  | -                waiting.append(task_meta)
 | 
	
		
			
				|  |  | -            self.unlock()
 | 
	
		
			
				|  |  | +        for task_meta in self.all():
 | 
	
		
			
				|  |  | +            if task_meta.name in periodic_tasks:
 | 
	
		
			
				|  |  | +                task = periodic_tasks[task_meta.name]
 | 
	
		
			
				|  |  | +                run_every = task.run_every
 | 
	
		
			
				|  |  | +                if self.is_time(task_meta.last_run_at, run_every):
 | 
	
		
			
				|  |  | +                    # Get the object again to be sure noone else
 | 
	
		
			
				|  |  | +                    # has already taken care of it.
 | 
	
		
			
				|  |  | +                    self.lock()
 | 
	
		
			
				|  |  | +                    try:
 | 
	
		
			
				|  |  | +                        secure = self.get(pk=task_meta.pk)
 | 
	
		
			
				|  |  | +                        if self.is_time(secure.last_run_at, run_every):
 | 
	
		
			
				|  |  | +                            secure.last_run_at = datetime.now()
 | 
	
		
			
				|  |  | +                            secure.save()
 | 
	
		
			
				|  |  | +                            waiting.append(secure)
 | 
	
		
			
				|  |  | +                    finally:
 | 
	
		
			
				|  |  | +                        self.unlock()
 | 
	
		
			
				|  |  |          return waiting
 |