123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375 |
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-
- <title>Canvas: Building Workflows — Celery 2.6.0rc4 documentation</title>
-
- <link rel="stylesheet" href="../_static/celery.css" type="text/css" />
- <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
- <link rel="stylesheet" href="../_static/issuetracker.css" type="text/css" />
-
- <script type="text/javascript">
- var DOCUMENTATION_OPTIONS = {
- URL_ROOT: '../',
- VERSION: '2.6.0rc4',
- COLLAPSE_INDEX: false,
- FILE_SUFFIX: '.html',
- HAS_SOURCE: true
- };
- </script>
- <script type="text/javascript" src="../_static/jquery.js"></script>
- <script type="text/javascript" src="../_static/underscore.js"></script>
- <script type="text/javascript" src="../_static/doctools.js"></script>
- <link rel="top" title="Celery 2.6.0rc4 documentation" href="../index.html" />
- <link rel="up" title="User Guide" href="index.html" />
- <link rel="next" title="HTTP Callback Tasks (Webhooks)" href="remote-tasks.html" />
- <link rel="prev" title="Periodic Tasks" href="periodic-tasks.html" />
- </head>
- <body>
- <div class="related">
- <h3>Navigation</h3>
- <ul>
- <li class="right" style="margin-right: 10px">
- <a href="../genindex.html" title="General Index"
- accesskey="I">index</a></li>
- <li class="right" >
- <a href="../py-modindex.html" title="Python Module Index"
- >modules</a> |</li>
- <li class="right" >
- <a href="remote-tasks.html" title="HTTP Callback Tasks (Webhooks)"
- accesskey="N">next</a> |</li>
- <li class="right" >
- <a href="periodic-tasks.html" title="Periodic Tasks"
- accesskey="P">previous</a> |</li>
- <li><a href="../index.html">Celery 2.6.0rc4 documentation</a> »</li>
- <li><a href="index.html" accesskey="U">User Guide</a> »</li>
- </ul>
- </div>
- <div class="document">
- <div class="documentwrapper">
- <div class="bodywrapper">
- <div class="body">
-
- <div class="deck">
-
- <p class="developmentversion">
- This document is for Celery's development version, which can be
- significantly different from previous releases. Get old docs here:
- <a href="http://docs.celeryproject.org/en/latest/userguide/canvas.html">2.5</a>.
- </p>
-
- </div>
- <div class="section" id="canvas-building-workflows">
- <span id="guide-canvas"></span><h1>Canvas: Building Workflows<a class="headerlink" href="#canvas-building-workflows" title="Permalink to this headline">¶</a></h1>
- <div class="contents local topic" id="contents">
- <ul class="simple">
- <li><a class="reference internal" href="#subtasks" id="id2">Subtasks</a><ul>
- <li><a class="reference internal" href="#callbacks" id="id3">Callbacks</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#groups" id="id4">Groups</a><ul>
- <li><a class="reference internal" href="#group-results" id="id5">Group Results</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#chords" id="id6">Chords</a><ul>
- <li><a class="reference internal" href="#important-notes" id="id7">Important Notes</a></li>
- </ul>
- </li>
- </ul>
- </div>
- <div class="section" id="subtasks">
- <span id="canvas-subtasks"></span><h2><a class="toc-backref" href="#id2">Subtasks</a><a class="headerlink" href="#subtasks" title="Permalink to this headline">¶</a></h2>
- <p class="versionadded">
- <span class="versionmodified">New in version 2.0.</span></p>
- <p>The <a class="reference internal" href="../reference/celery.html#celery.subtask" title="celery.subtask"><tt class="xref py py-class docutils literal"><span class="pre">subtask</span></tt></a> type is used to wrap the arguments and
- execution options for a single task invocation:</p>
- <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">celery</span> <span class="kn">import</span> <span class="n">subtask</span>
- <span class="n">subtask</span><span class="p">(</span><span class="n">task_name_or_cls</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>For convenience every task also has a shortcut to create subtasks:</p>
- <div class="highlight-python"><div class="highlight"><pre><span class="n">task</span><span class="o">.</span><span class="n">subtask</span><span class="p">(</span><span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../reference/celery.html#celery.subtask" title="celery.subtask"><tt class="xref py py-class docutils literal"><span class="pre">subtask</span></tt></a> is actually a <a class="reference external" href="http://docs.python.org/dev/library/stdtypes.html#dict" title="(in Python v3.3)"><tt class="xref py py-class docutils literal"><span class="pre">dict</span></tt></a> subclass,
- which means it can be serialized with JSON or other encodings that doesn’t
- support complex Python objects.</p>
- <p>Also it can be regarded as a type, as the following usage works:</p>
- <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">s</span> <span class="o">=</span> <span class="n">subtask</span><span class="p">(</span><span class="s">"tasks.add"</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="n">kwargs</span><span class="o">=</span><span class="p">{})</span>
- <span class="gp">>>> </span><span class="n">subtask</span><span class="p">(</span><span class="nb">dict</span><span class="p">(</span><span class="n">s</span><span class="p">))</span> <span class="c"># coerce dict into subtask</span>
- </pre></div>
- </div>
- <p>This makes it excellent as a means to pass callbacks around to tasks.</p>
- <div class="section" id="callbacks">
- <span id="canvas-callbacks"></span><h3><a class="toc-backref" href="#id3">Callbacks</a><a class="headerlink" href="#callbacks" title="Permalink to this headline">¶</a></h3>
- <p>Callbacks can be added to any task using the <tt class="docutils literal"><span class="pre">link</span></tt> argument
- to <tt class="docutils literal"><span class="pre">apply_async</span></tt>:</p>
- <blockquote>
- <div>add.apply_async((2, 2), link=other_task.subtask())</div></blockquote>
- <p>The callback will only be applied if the task exited successfully,
- and it will be applied with the return value of the parent task as argument.</p>
- <p>The best thing is that any arguments you add to <cite>subtask</cite>,
- will be prepended to the arguments specified by the subtask itself!</p>
- <p>If you have the subtask:</p>
- <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">add</span><span class="o">.</span><span class="n">subtask</span><span class="p">(</span><span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="p">))</span>
- </pre></div>
- </div>
- <p><cite>subtask.delay(result)</cite> becomes:</p>
- <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">add</span><span class="o">.</span><span class="n">apply_async</span><span class="p">(</span><span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="mi">10</span><span class="p">))</span>
- </pre></div>
- </div>
- <p>...</p>
- <p>Now let’s call our <tt class="docutils literal"><span class="pre">add</span></tt> task with a callback using partial
- arguments:</p>
- <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">add</span><span class="o">.</span><span class="n">apply_async</span><span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="n">link</span><span class="o">=</span><span class="n">add</span><span class="o">.</span><span class="n">subtask</span><span class="p">((</span><span class="mi">8</span><span class="p">,</span> <span class="p">)))</span>
- </pre></div>
- </div>
- <p>As expected this will first launch one task calculating <img class="math" src="../_images/math/2da3a5ecd44fdb54a9a30c87a48a5b1638c139b0.png" alt="2 + 2"/>, then
- another task calculating <img class="math" src="../_images/math/c67562ae31bb2d1017a9b0240c012edc474851c3.png" alt="4 + 8"/>.</p>
- </div>
- </div>
- <div class="section" id="groups">
- <span id="canvas-group"></span><h2><a class="toc-backref" href="#id4">Groups</a><a class="headerlink" href="#groups" title="Permalink to this headline">¶</a></h2>
- <p>The <a class="reference internal" href="../reference/celery.html#celery.group" title="celery.group"><tt class="xref py py-class docutils literal"><span class="pre">group</span></tt></a> enables easy invocation of several
- tasks at once, and is then able to join the results in the same order as the
- tasks were invoked.</p>
- <p><tt class="docutils literal"><span class="pre">group</span></tt> takes a list of <a class="reference internal" href="../reference/celery.html#celery.subtask" title="celery.subtask"><tt class="xref py py-class docutils literal"><span class="pre">subtask</span></tt></a>‘s:</p>
- <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">celery</span> <span class="kn">import</span> <span class="n">group</span>
- <span class="gp">>>> </span><span class="kn">from</span> <span class="nn">tasks</span> <span class="kn">import</span> <span class="n">add</span>
- <span class="gp">>>> </span><span class="n">job</span> <span class="o">=</span> <span class="n">group</span><span class="p">([</span>
- <span class="gp">... </span> <span class="n">add</span><span class="o">.</span><span class="n">subtask</span><span class="p">((</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">)),</span>
- <span class="gp">... </span> <span class="n">add</span><span class="o">.</span><span class="n">subtask</span><span class="p">((</span><span class="mi">4</span><span class="p">,</span> <span class="mi">4</span><span class="p">)),</span>
- <span class="gp">... </span> <span class="n">add</span><span class="o">.</span><span class="n">subtask</span><span class="p">((</span><span class="mi">8</span><span class="p">,</span> <span class="mi">8</span><span class="p">)),</span>
- <span class="gp">... </span> <span class="n">add</span><span class="o">.</span><span class="n">subtask</span><span class="p">((</span><span class="mi">16</span><span class="p">,</span> <span class="mi">16</span><span class="p">)),</span>
- <span class="gp">... </span> <span class="n">add</span><span class="o">.</span><span class="n">subtask</span><span class="p">((</span><span class="mi">32</span><span class="p">,</span> <span class="mi">32</span><span class="p">)),</span>
- <span class="gp">... </span><span class="p">])</span>
- <span class="gp">>>> </span><span class="n">result</span> <span class="o">=</span> <span class="n">job</span><span class="o">.</span><span class="n">apply_async</span><span class="p">()</span>
- <span class="gp">>>> </span><span class="n">result</span><span class="o">.</span><span class="n">ready</span><span class="p">()</span> <span class="c"># have all subtasks completed?</span>
- <span class="go">True</span>
- <span class="gp">>>> </span><span class="n">result</span><span class="o">.</span><span class="n">successful</span><span class="p">()</span> <span class="c"># were all subtasks successful?</span>
- <span class="go">True</span>
- <span class="gp">>>> </span><span class="n">result</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
- <span class="go">[4, 8, 16, 32, 64]</span>
- </pre></div>
- </div>
- <p>The first argument can alternatively be an iterator, like:</p>
- <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">group</span><span class="p">(</span><span class="n">add</span><span class="o">.</span><span class="n">subtask</span><span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="n">i</span><span class="p">))</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">100</span><span class="p">))</span>
- </pre></div>
- </div>
- <div class="section" id="group-results">
- <span id="canvas-group-results"></span><h3><a class="toc-backref" href="#id5">Group Results</a><a class="headerlink" href="#group-results" title="Permalink to this headline">¶</a></h3>
- <p>When a <a class="reference internal" href="../reference/celery.html#celery.group" title="celery.group"><tt class="xref py py-class docutils literal"><span class="pre">group</span></tt></a> is applied it returns a
- <a class="reference internal" href="../reference/celery.result.html#celery.result.GroupResult" title="celery.result.GroupResult"><tt class="xref py py-class docutils literal"><span class="pre">GroupResult</span></tt></a> object.</p>
- <p><a class="reference internal" href="../reference/celery.result.html#celery.result.GroupResult" title="celery.result.GroupResult"><tt class="xref py py-class docutils literal"><span class="pre">GroupResult</span></tt></a> takes a list of
- <a class="reference internal" href="../reference/celery.result.html#celery.result.AsyncResult" title="celery.result.AsyncResult"><tt class="xref py py-class docutils literal"><span class="pre">AsyncResult</span></tt></a> instances and operates on them as if it was a
- single task.</p>
- <p>It supports the following operations:</p>
- <ul>
- <li><p class="first"><tt class="xref py py-meth docutils literal"><span class="pre">successful()</span></tt></p>
- <blockquote>
- <div><p>Returns <tt class="xref py py-const docutils literal"><span class="pre">True</span></tt> if all of the subtasks finished
- successfully (e.g. did not raise an exception).</p>
- </div></blockquote>
- </li>
- <li><p class="first"><tt class="xref py py-meth docutils literal"><span class="pre">failed()</span></tt></p>
- <blockquote>
- <div><p>Returns <tt class="xref py py-const docutils literal"><span class="pre">True</span></tt> if any of the subtasks failed.</p>
- </div></blockquote>
- </li>
- <li><p class="first"><tt class="xref py py-meth docutils literal"><span class="pre">waiting()</span></tt></p>
- <blockquote>
- <div><p>Returns <tt class="xref py py-const docutils literal"><span class="pre">True</span></tt> if any of the subtasks
- is not ready yet.</p>
- </div></blockquote>
- </li>
- <li><p class="first"><tt class="xref py py-meth docutils literal"><span class="pre">ready()</span></tt></p>
- <blockquote>
- <div><p>Return <tt class="xref py py-const docutils literal"><span class="pre">True</span></tt> if all of the subtasks
- are ready.</p>
- </div></blockquote>
- </li>
- <li><p class="first"><tt class="xref py py-meth docutils literal"><span class="pre">completed_count()</span></tt></p>
- <blockquote>
- <div><p>Returns the number of completed subtasks.</p>
- </div></blockquote>
- </li>
- <li><p class="first"><tt class="xref py py-meth docutils literal"><span class="pre">revoke()</span></tt></p>
- <blockquote>
- <div><p>Revokes all of the subtasks.</p>
- </div></blockquote>
- </li>
- <li><p class="first"><tt class="xref py py-meth docutils literal"><span class="pre">iterate()</span></tt></p>
- <blockquote>
- <div><p>Iterates over the return values of the subtasks
- as they finish, one by one.</p>
- </div></blockquote>
- </li>
- <li><p class="first"><tt class="xref py py-meth docutils literal"><span class="pre">join()</span></tt></p>
- <blockquote>
- <div><p>Gather the results for all of the subtasks
- and return a list with them ordered by the order of which they
- were called.</p>
- </div></blockquote>
- </li>
- </ul>
- </div>
- </div>
- <div class="section" id="chords">
- <span id="id1"></span><h2><a class="toc-backref" href="#id6">Chords</a><a class="headerlink" href="#chords" title="Permalink to this headline">¶</a></h2>
- <p class="versionadded">
- <span class="versionmodified">New in version 2.3.</span></p>
- <p>A chord is a task that only executes after all of the tasks in a taskset has
- finished executing.</p>
- <p>Let’s calculate the sum of the expression
- <img class="math" src="../_images/math/c9bf2df3c397d6399241c37fc9887ca50bc8fa09.png" alt="1 + 1 + 2 + 2 + 3 + 3 ... n + n"/> up to a hundred digits.</p>
- <p>First we need two tasks, <tt class="xref py py-func docutils literal"><span class="pre">add()</span></tt> and <tt class="xref py py-func docutils literal"><span class="pre">tsum()</span></tt> (<a class="reference external" href="http://docs.python.org/dev/library/functions.html#sum" title="(in Python v3.3)"><tt class="xref py py-func docutils literal"><span class="pre">sum()</span></tt></a> is
- already a standard function):</p>
- <div class="highlight-python"><div class="highlight"><pre><span class="nd">@celery.task</span><span class="p">()</span>
- <span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
- <span class="k">return</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span>
- <span class="nd">@celery.task</span><span class="p">()</span>
- <span class="k">def</span> <span class="nf">tsum</span><span class="p">(</span><span class="n">numbers</span><span class="p">):</span>
- <span class="k">return</span> <span class="nb">sum</span><span class="p">(</span><span class="n">numbers</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>Now we can use a chord to calculate each addition step in parallel, and then
- get the sum of the resulting numbers:</p>
- <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="kn">from</span> <span class="nn">celery</span> <span class="kn">import</span> <span class="n">chord</span>
- <span class="gp">>>> </span><span class="kn">from</span> <span class="nn">tasks</span> <span class="kn">import</span> <span class="n">add</span><span class="p">,</span> <span class="n">tsum</span>
- <span class="gp">>>> </span><span class="n">chord</span><span class="p">(</span><span class="n">add</span><span class="o">.</span><span class="n">subtask</span><span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="n">i</span><span class="p">))</span>
- <span class="gp">... </span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">100</span><span class="p">))(</span><span class="n">tsum</span><span class="o">.</span><span class="n">subtask</span><span class="p">())</span><span class="o">.</span><span class="n">get</span><span class="p">()</span>
- <span class="go">9900</span>
- </pre></div>
- </div>
- <p>This is obviously a very contrived example, the overhead of messaging and
- synchronization makes this a lot slower than its Python counterpart:</p>
- <div class="highlight-python"><div class="highlight"><pre><span class="nb">sum</span><span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">100</span><span class="p">))</span>
- </pre></div>
- </div>
- <p>The synchronization step is costly, so you should avoid using chords as much
- as possible. Still, the chord is a powerful primitive to have in your toolbox
- as synchronization is a required step for many parallel algorithms.</p>
- <p>Let’s break the chord expression down:</p>
- <div class="highlight-python"><div class="highlight"><pre><span class="gp">>>> </span><span class="n">callback</span> <span class="o">=</span> <span class="n">tsum</span><span class="o">.</span><span class="n">subtask</span><span class="p">()</span>
- <span class="gp">>>> </span><span class="n">header</span> <span class="o">=</span> <span class="p">[</span><span class="n">add</span><span class="o">.</span><span class="n">subtask</span><span class="p">((</span><span class="n">i</span><span class="p">,</span> <span class="n">i</span><span class="p">))</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">xrange</span><span class="p">(</span><span class="mi">100</span><span class="p">)]</span>
- <span class="gp">>>> </span><span class="n">result</span> <span class="o">=</span> <span class="n">chord</span><span class="p">(</span><span class="n">header</span><span class="p">)(</span><span class="n">callback</span><span class="p">)</span>
- <span class="gp">>>> </span><span class="n">result</span><span class="o">.</span><span class="n">get</span><span class="p">()</span>
- <span class="go">9900</span>
- </pre></div>
- </div>
- <p>Remember, the callback can only be executed after all of the tasks in the
- header has returned. Each step in the header is executed as a task, in
- parallel, possibly on different nodes. The callback is then applied with
- the return value of each task in the header. The task id returned by
- <tt class="xref py py-meth docutils literal"><span class="pre">chord()</span></tt> is the id of the callback, so you can wait for it to complete
- and get the final return value (but remember to <a class="reference internal" href="tasks.html#task-synchronous-subtasks"><em>never have a task wait
- for other tasks</em></a>)</p>
- <div class="section" id="important-notes">
- <span id="chord-important-notes"></span><h3><a class="toc-backref" href="#id7">Important Notes</a><a class="headerlink" href="#important-notes" title="Permalink to this headline">¶</a></h3>
- <p>By default the synchronization step is implemented by having a recurring task
- poll the completion of the taskset every second, applying the subtask when
- ready.</p>
- <p>Example implementation:</p>
- <div class="highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">unlock_chord</span><span class="p">(</span><span class="n">taskset</span><span class="p">,</span> <span class="n">callback</span><span class="p">,</span> <span class="n">interval</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">max_retries</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
- <span class="k">if</span> <span class="n">taskset</span><span class="o">.</span><span class="n">ready</span><span class="p">():</span>
- <span class="k">return</span> <span class="n">subtask</span><span class="p">(</span><span class="n">callback</span><span class="p">)</span><span class="o">.</span><span class="n">delay</span><span class="p">(</span><span class="n">taskset</span><span class="o">.</span><span class="n">join</span><span class="p">())</span>
- <span class="k">raise</span> <span class="n">unlock_chord</span><span class="o">.</span><span class="n">retry</span><span class="p">(</span><span class="n">countdown</span><span class="o">=</span><span class="n">interval</span><span class="p">,</span> <span class="n">max_retries</span><span class="o">=</span><span class="n">max_retries</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>This is used by all result backends except Redis and Memcached, which increment a
- counter after each task in the header, then applying the callback when the
- counter exceeds the number of tasks in the set. <em>Note:</em> chords do not properly
- work with Redis before version 2.2; you will need to upgrade to at least 2.2 to
- use them.</p>
- <p>The Redis and Memcached approach is a much better solution, but not easily
- implemented in other backends (suggestions welcome!).</p>
- <div class="admonition note">
- <p class="first admonition-title">Note</p>
- <p>If you are using chords with the Redis result backend and also overriding
- the <tt class="xref py py-meth docutils literal"><span class="pre">Task.after_return()</span></tt> method, you need to make sure to call the
- super method or else the chord callback will not be applied.</p>
- <div class="last highlight-python"><div class="highlight"><pre><span class="k">def</span> <span class="nf">after_return</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
- <span class="n">do_something</span><span class="p">()</span>
- <span class="nb">super</span><span class="p">(</span><span class="n">MyTask</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">after_return</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
- </pre></div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="sphinxsidebar">
- <div class="sphinxsidebarwrapper"><p class="logo"><a href="../index.html">
- <img class="logo" src="http://cloud.github.com/downloads/celery/celery/celery_128.png" alt="Logo"/>
- </a></p>
- <h4>Previous topic</h4>
- <p class="topless"><a href="periodic-tasks.html"
- title="previous chapter">Periodic Tasks</a></p>
- <h4>Next topic</h4>
- <p class="topless"><a href="remote-tasks.html"
- title="next chapter">HTTP Callback Tasks (Webhooks)</a></p>
- <h3>This Page</h3>
- <ul class="this-page-menu">
- <li><a href="../_sources/userguide/canvas.txt"
- rel="nofollow">Show Source</a></li>
- </ul>
- <div id="searchbox" style="display: none">
- <h3>Quick search</h3>
- <form class="search" action="../search.html" method="get">
- <input type="text" name="q" />
- <input type="submit" value="Go" />
- <input type="hidden" name="check_keywords" value="yes" />
- <input type="hidden" name="area" value="default" />
- </form>
- <p class="searchtip" style="font-size: 90%">
- Enter search terms or a module, class or function name.
- </p>
- </div>
- <script type="text/javascript">$('#searchbox').show(0);</script>
- </div>
- </div>
- <div class="clearer"></div>
- </div>
- <div class="related">
- <h3>Navigation</h3>
- <ul>
- <li class="right" style="margin-right: 10px">
- <a href="../genindex.html" title="General Index"
- >index</a></li>
- <li class="right" >
- <a href="../py-modindex.html" title="Python Module Index"
- >modules</a> |</li>
- <li class="right" >
- <a href="remote-tasks.html" title="HTTP Callback Tasks (Webhooks)"
- >next</a> |</li>
- <li class="right" >
- <a href="periodic-tasks.html" title="Periodic Tasks"
- >previous</a> |</li>
- <li><a href="../index.html">Celery 2.6.0rc4 documentation</a> »</li>
- <li><a href="index.html" >User Guide</a> »</li>
- </ul>
- </div>
- <div class="footer">
- © Copyright 2009-2012, Ask Solem & Contributors.
- </div>
- </body>
- </html>
|