title: celery - call function on task done
body: <p>I'm using celery with django and rabbitmq to create a message queue. I also have a worker, which is originating from a different machine. In a django view I'm starting a process like this:</p>
  
  <pre><code>def processtask(request, name):
    args = ["ls", "-l"]
    MyTask.delay(args)
    return HttpResponse("Task set to execute.")
  </code></pre>
  
  <p>My task is configured like this:</p>
  
  <pre><code>class MyTask(Task):
    def run(self, args):
      p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
      (out, err) = p.communicate()
      return out
  </code></pre>
  
  <p>My question now is how can a broker (my django project) now receive the output from the "ls -l" command that the worker executed on his computer. I guess the best thing would be for worker to call a function in broker whenever it's ready to send the output from the executed command. </p>
  
  <p>I would like to receive the output from worker asynchronously, then update the webpage with the output, but that's for another time. For now I would only like to receive the output from worker. </p>
  
  <p><strong>Update</strong></p>
  
  <p>Right now I've added a HTTP GET request that is triggered at the end of task notifying the web application that the task is done - I'm also sending the task_id in the http GET. The http GET method calls django view, which creates AsyncResult and gets the result, but the problem is that when calling <strong>result.get()</strong> I get the following error:</p>
  
  <pre><code>/usr/lib64/python2.6/site-packages/django_celery-2.5.1-py2.6.egg/djcelery/managers.py:178: TxIsolationWarning: Polling results with transaction isolation level repeatable-read within the same transaction may give outdated results. Be sure to commit the transaction for each poll iteration.
    "Polling results with transaction isolation level"
  </code></pre>
  
  <p>Any ideas why? I'm not using database, because I'm using rabbitmq with AMQP.</p>
  
  <p>Update.</p>
  
  <p>I would very much like to use third option, which seems like the best option - for small and big return values. My whole task looks like this:</p>
  
  <pre><code>class MyTask(Task):
    def __call__(self, *args, **kwargs):
      return self.run(*args, **kwargs)
  
    def after_return(self, status, retval, task_id, args, kwargs, einfo):
      if self.webhost is not None:
        conn = httplib.HTTPConnection(self.webhost, self.webport)
        conn.request("HEAD", "/vuln/task/output/"+task_id)
  
    def run(self, args, webhost=None, webport=None):
      self.webhost = webhost
      self.webport = webport
      r = "This is a basic result string used for code clarity"
      return r
  </code></pre>
  
  <p>So I've overridden the after_return function, which should also release the lock on my task, since the task's run() function already returned a value. In the HEAD request I'm basically calling a django function, which calls AsyncResult on task_id, which should provide with the result of the task. I've used arbitrary result for testing purposes in my case, since it's only for testing.</p>
  
  <p>I would like to know why the above code doesn't work. I can use on_success, but I don't think it will make a difference - or will it?</p>