| 
					
				 | 
			
			
				@@ -7,11 +7,13 @@ from celery.registry import tasks 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from celery.exceptions import NotRegistered 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from celery.execute import ExecuteWrapper 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from celery.utils import noop, fun_takes_kwargs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+from celery.log import get_default_logger 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from django.core.mail import mail_admins 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import multiprocessing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import socket 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import sys 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # pep8.py borks on a inline signature separator and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # says "trailing whitespace" ;) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 EMAIL_SIGNATURE_SEP = "-- " 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -19,19 +21,26 @@ TASK_FAIL_EMAIL_BODY = """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 Task %%(name)s with id %%(id)s raised exception: %%(exc)s 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-Task was called with args:%%(args)s kwargs:%%(kwargs)s. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Task was called with args: %%(args)s kwargs: %%(kwargs)s. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 The contents of the full traceback was: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 %%(traceback)s 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 %(EMAIL_SIGNATURE_SEP)s 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-Just thought I'd let you know! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Just to let you know, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 celeryd at %%(hostname)s. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 """ % {"EMAIL_SIGNATURE_SEP": EMAIL_SIGNATURE_SEP} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class AlreadyExecutedError(Exception): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """Tasks can only be executed once, as they might change 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    world-wide state.""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class TaskWrapper(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    """Class wrapping a task to be run. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """Class wrapping a task to be passed around and finally 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    executed inside of the worker. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     :param task_name: see :attr:`task_name`. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -67,6 +76,11 @@ class TaskWrapper(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         The original message sent. Used for acknowledging the message. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .. attribute executed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Set if the task has been executed. A task should only be executed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    once. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     success_msg = "Task %(name)s[%(id)s] processed: %(return_value)s" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fail_msg = """ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -87,11 +101,12 @@ class TaskWrapper(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.kwargs = kwargs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.logger = kwargs.get("logger") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.on_ack = on_ack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.executed = False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         for opt in ("success_msg", "fail_msg", "fail_email_subject", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 "fail_email_body"): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             setattr(self, opt, opts.get(opt, getattr(self, opt, None))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if not self.logger: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            self.logger = multiprocessing.get_logger() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.logger = get_default_logger() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def __repr__(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return '<%s: {name:"%s", id:"%s", args:"%s", kwargs:"%s"}>' % ( 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -154,6 +169,13 @@ class TaskWrapper(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return ExecuteWrapper(self.task_func, self.task_id, self.task_name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                               self.args, task_func_kwargs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def _set_executed_bit(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if self.executed: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            raise AlreadyExecutedError( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                   "Task %s[%s] has already been executed" % ( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       self.task_name, self.task_id)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.executed = True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def execute(self, loglevel=None, logfile=None): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """Execute the task in a :class:`celery.execute.ExecuteWrapper`. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -162,6 +184,9 @@ class TaskWrapper(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         :keyword logfile: The logfile used by the task. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # Make sure task has not already been executed. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self._set_executed_bit() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # acknowledge task as being processed. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.on_ack() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -179,6 +204,9 @@ class TaskWrapper(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         :returns :class:`multiprocessing.AsyncResult` instance. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # Make sure task has not already been executed. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self._set_executed_bit() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         wrapper = self._executeable(loglevel, logfile) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return pool.apply_async(wrapper, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 callbacks=[self.on_success], errbacks=[self.on_failure], 
			 |