File: posttask.rst

package info (click to toggle)
python-ruffus 2.6.3%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 20,828 kB
  • ctags: 2,843
  • sloc: python: 15,745; makefile: 180; sh: 14
file content (122 lines) | stat: -rw-r--r-- 4,096 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
.. include:: ../../global.inc
.. include:: manual_chapter_numbers.inc

.. index::
    pair: posttask; Tutorial

.. _new_manual.posttask:

####################################################################################################################################################
|new_manual.posttask.chapter_num|: Signal the completion of each stage of our pipeline with :ref:`@posttask <decorators.posttask>`
####################################################################################################################################################


.. seealso::

   * :ref:`Manual Table of Contents <new_manual.table_of_contents>`
   * :ref:`@posttask <decorators.posttask>` syntax


***********************
Overview
***********************



    It is often useful to signal the completion of each task by specifying a specific
    action to be taken or function to be called. This can range from
    printing out some message, or  `touching  <http://en.wikipedia.org/wiki/Touch_(Unix)>`__ some sentinel file,
    to emailing the author. This is particular useful if the :term:`task` is a recipe apply to an unspecified number
    of parameters in parallel in different :term:`job`\ s. If the task is never run, or if it
    fails, needless-to-say no task completion action will happen.


    *Ruffus* uses the :ref:`@posttask <decorators.posttask>` decorator for this purpose.


=================
**@posttask**
=================

    We can signal the completion of each task by specifying
    one or more function(s) using :ref:`@posttask <decorators.posttask>` ::

        from ruffus import *

        def task_finished():
            print "hooray"

        @posttask(task_finished)
        @originate("a.1")
        def create_if_necessary(output_file):
            open(output_file, "w")

        pipeline_run([create_if_necessary])


    This is such a short function, we might as well write it in-line:

        ::

            @posttask(lambda: sys.stdout.write("hooray\n"))
            @originate("a.1")
            def create_if_necessary(output_file):
                open(output_file, "w")


.. note::

    The function(s) provided to :ref:`@posttask <decorators.posttask>` will be called if the pipeline passes
    through a task, even if none of its jobs are run because they are up-to-date.
    This happens when a upstream task is out-of-date, and the execution passes through
    this point in the pipeline. See the example in :ref:`new_manual.dependencies`
    of this manual.


.. index::
    single: @posttask; touchfile (Manual)
    single: touchfile ; @posttask (Manual)


.. _new_manual.posttask.touch_file:

============================================
:ref:`touch_file<decorators.touch_file>`
============================================

    One way to note the completion of a task is to create some sort of
    "flag" file. Each stage in a traditional ``make`` pipeline would contain a
    ``touch completed.flag``.

    This is such a useful idiom that *Ruffus* provides the shorthand :ref:`touch_file<decorators.touch_file>`:

        .. code-block:: python

            from ruffus import *

            @posttask(touch_file("task_completed.flag"))
            @files(None, "a.1")
            def create_if_necessary(input_file, output_file):
                open(output_file, "w")

            pipeline_run()

=======================================
Adding several post task actions
=======================================
    You can, of course, add more than one different action to be taken on completion of the
    task, either by stacking up as many :ref:`@posttask<decorators.posttask>` decorators
    as necessary, or by including several functions in the same :ref:`@posttask <decorators.posttask>`:

        .. code-block:: python

            from ruffus import *

            @posttask(print_hooray, print_whoppee)
            @posttask(print_hip_hip, touch_file("sentinel_flag"))
            @originate("a.1")
            def create_if_necessary(output_file):
                open(output_file, "w")

            pipeline_run()