title: Python / Celery : how can I kill subtasks when killing a parent task?
body: <p><strong>Context</strong></p>
  
  <p>I've created a Django application that is calling a celery task which in turns spawn other tasks and wait for them to be finished.</p>
  
  <p>Here's the workflow :</p>
  
  <p>1) The main python/django code start a celery task in the background</p>
  
  <p>2) The celery task process some code and then start a celery group of differents tasks and wait for them to be ready</p>
  
  <p>3) every task of the group then spawn another group of subtasks in the same way and wait for them to finish</p>
  
  <p>It works well (although I'm a begginer and probably implemented it poorly) but now I would like to be able to terminate every child processes if I kill the main celery tasks started in the beggining.</p>
  
  <p><strong>What I have so far</strong></p>
  
  <p>I've recreated the situation using a simple parent tasks spawning multiple child tasks and i've modified the "on_failure" method of the celery Task class to kill it's child when it fails.</p>
  
  <p><em>Tasks.py</em></p>
  
  <pre><code>from celery import Celery, group,Task, result
  from celery.signals import task_revoked
  import time
  from pprint import pprint
  application = Celery('tasks',backend='amqp://',broker='amqp://guest@localhost//')
  
  
  class MyTask(Task):
      def on_failure(self, exc, task_id, args, kwargs, einfo):
          print(self.AsyncResult(task_id).children[0].revoke(terminate=True,signal='SIGTERM'))
          print('{0!r} failed: {1!r}'.format(task_id, exc))
  
  @application.task(base=MyTask)
  def childTask():
      while True:
          time.sleep(10)
          print("Message de la tache enfant")
          continue
  
  @application.task(base=MyTask)
  def parentTask(pra_id = None):
      child_tasks = []
      print("Lancement tache mère")
      child_tasks.append(childTask.s())
      child_tasks.append(childTask.s())
      child_tasks.append(childTask.s())
      tasks = group(child_tasks)
      tasks.apply_async()
  
      time.sleep(15)
      raise KeyError
  </code></pre>
  
  <p><em>main.py</em></p>
  
  <pre><code>from tasks import parentTask
  
  parent1 = parentTask.delay(pra_id = 10)
  parent2 = parentTask.delay(pra_id = 20)
  </code></pre>
  
  <p>When the code raise an error, the parent task gets killed succesfully and its child tasks too, this is what I want.</p>
  
  <p><strong>What I need</strong></p>
  
  <p>I need to be able to manually kill my parent task from my django application.</p>
  
  <p>This is done by inspecting the celery worker and finding my task by searching for it's arguments, this was successfully done, however, When I manually revoke the celery task once I find it, it does not terminate the child tasks spawned by this task and that's what I need.</p>
  
  <p><strong>What I've tried so far</strong></p>
  
  <p>I've tried to create a function triggered by the "revoke" signal </p>
  
  <p>(<a href="http://docs.celeryproject.org/en/latest/userguide/signals.html#task-revoked" rel="nofollow noreferrer">http://docs.celeryproject.org/en/latest/userguide/signals.html#task-revoked</a>) </p>
  
  <p>that would execute when a task is revoked.</p>
  
  <p>Capturing the signal worked (I was able to execute some code when revoking a task) but I was not able to use the same code as my "On_failure" method described above) to kill the childs tasks.</p>
  
  <p><strong>Problem</strong></p>
  
  <p>The Request object sent to the function does contain my parent Task but the "children" property of the class is empty when it should contain a GroupResult object containing the child tasks.</p>