Example #1
0
 def get_prereq(self, point):
     """Return a prerequisite string."""
     if self.message:
         # Message trigger
         preq = self.message
         msg_point = point
         if self.cycle_point:
             point = self.cycle_point
             msg_point = self.cycle_point
         else:
             if self.message_offset:
                 msg_point = point + self.message_offset
             if self.graph_offset_string:
                 msg_point = get_point_relative(
                     self.graph_offset_string, msg_point)
                 point = get_point_relative(self.graph_offset_string, point)
         preq = "%s %s" % (
             TaskID.get(self.task_name, point),
             re.sub('\[.*\]', str(msg_point), preq))
     else:
         # Built-in trigger
         if self.cycle_point:
             point = self.cycle_point
         elif self.graph_offset_string:
             point = get_point_relative(
                 self.graph_offset_string, point)
         preq = TaskID.get(self.task_name, point) + ' ' + self.builtin
     return preq
Example #2
0
    def _add_prerequisites(self, point, identity, tdef):
        """Add task prerequisites."""
        # self.triggers[sequence] = [triggers for sequence]
        # Triggers for sequence_i only used if my cycle point is a
        # valid member of sequence_i's sequence of cycle points.
        self._recalc_satisfied = True

        for sequence, exps in tdef.triggers.items():
            for ctrig, exp in exps:
                key = ctrig.keys()[0]
                if not sequence.is_valid(point):
                    # This trigger is not valid for current cycle (see NOTE
                    # just above)
                    continue

                cpre = Prerequisite(identity, point, tdef.start_point)

                for label in ctrig:
                    trig = ctrig[label]
                    if trig.graph_offset_string is not None:
                        prereq_offset_point = get_point_relative(
                            trig.graph_offset_string, point)
                        if prereq_offset_point > point:
                            prereq_offset = prereq_offset_point - point
                            if (tdef.max_future_prereq_offset is None or
                                    (prereq_offset >
                                     tdef.max_future_prereq_offset)):
                                tdef.max_future_prereq_offset = (
                                    prereq_offset)
                        cpre.add(trig.get_prereq(point), label,
                                 ((prereq_offset_point < tdef.start_point) &
                                  (point >= tdef.start_point)))
                    else:
                        cpre.add(trig.get_prereq(point), label)
                cpre.set_condition(exp)
                if ctrig[key].suicide:
                    self.suicide_prerequisites.append(cpre)
                else:
                    self.prerequisites.append(cpre)

        if tdef.sequential:
            # Add a previous-instance succeeded prerequisite.
            p_prev = None
            adjusted = []
            for seq in tdef.sequences:
                prv = seq.get_nearest_prev_point(point)
                if prv:
                    # None if out of sequence bounds.
                    adjusted.append(prv)
            if adjusted:
                p_prev = max(adjusted)
                cpre = Prerequisite(identity, point, tdef.start_point)
                prereq = "%s %s" % (TaskID.get(tdef.name, p_prev),
                                    TASK_STATUS_SUCCEEDED)
                label = tdef.name
                cpre.add(prereq, label, p_prev < tdef.start_point)
                cpre.set_condition(label)
                self.prerequisites.append(cpre)
Example #3
0
    def get_cleanup_cutoff_point(cls, my_point, offset_sequence_tuples):
        """Extract the max dependent cycle point for this point."""
        if not offset_sequence_tuples:
            # This task does not have dependent tasks at other cycles.
            return my_point
        cutoff_points = []
        for offset_string, sequence in offset_sequence_tuples:
            if offset_string is None:
                # This indicates a dependency that lasts for the whole run.
                return None
            if sequence is None:
                # This indicates a simple offset interval such as [-PT6H].
                cutoff_points.append(
                    my_point - get_interval(offset_string))
                continue
            if is_offset_absolute(offset_string):
                stop_point = sequence.get_stop_point()
                if stop_point:
                    # Stop point of the sequence is a good cutoff point for an
                    # absolute "offset"
                    cutoff_points.append(stop_point)
                    continue
                else:
                    # The dependency lasts for the whole run.
                    return None

            # This is a complicated offset like [02T00-P1W].
            dependent_point = sequence.get_start_point()

            my_cutoff_point = None
            while dependent_point is not None:
                # TODO: Is it realistically possible to hang in this loop?
                target_point = (
                    get_point_relative(offset_string, dependent_point))
                if target_point > my_point:
                    # Assume monotonic (target_point can never jump back).
                    break
                if target_point == my_point:
                    # We have found a dependent_point for my_point.
                    my_cutoff_point = dependent_point
                dependent_point = sequence.get_next_point_on_sequence(
                    dependent_point)
            if my_cutoff_point:
                # Choose the largest of the dependent points.
                cutoff_points.append(my_cutoff_point)
        if cutoff_points:
            max_cutoff_point = max(cutoff_points)
            if max_cutoff_point < my_point:
                # This is caused by future triggers - default to my_point.
                return my_point
            return max_cutoff_point
        # There aren't any dependent tasks in other cycles for my_point.
        return my_point
Example #4
0
 def get(self, point):
     """Return a prerequisite string and the relevant point."""
     if self.message:
         # Message trigger
         preq = self.message
         if self.cycle_point:
             point = self.cycle_point
         else:
             if self.message_offset:
                 point += self.message_offset
             if self.graph_offset_string:
                 point = get_point_relative(self.graph_offset_string, point)
         preq = re.sub('\[.*\]', str(point), preq)
     else:
         # Built-in trigger
         if self.cycle_point:
             point = self.cycle_point
         elif self.graph_offset_string:
             point = get_point_relative(self.graph_offset_string, point)
         preq = cylc.TaskID.get(self.task_name,
                                str(point)) + ' ' + self.builtin
     return preq, point
Example #5
0
 def get_prereq(self, point):
     """Return a prerequisite string and the relevant point."""
     if self.message:
         # Message trigger
         preq = self.message
         if self.cycle_point:
             point = self.cycle_point
         else:
             if self.message_offset:
                 point += self.message_offset
             if self.graph_offset_string:
                 point = get_point_relative(self.graph_offset_string, point)
         preq = re.sub('\[.*\]', str(point), preq)
     else:
         # Built-in trigger
         if self.cycle_point:
             point = self.cycle_point
         elif self.graph_offset_string:
             point = get_point_relative(
                 self.graph_offset_string, point)
         preq = TaskID.get(self.task_name, point) + ' ' + self.builtin
     return preq, point
Example #6
0
    def get_graph(cls,
                  suiterc,
                  group_nodes=None,
                  ungroup_nodes=None,
                  ungroup_recursive=False,
                  group_all=False,
                  ungroup_all=False,
                  ignore_suicide=False,
                  subgraphs_on=False,
                  bgcolor=None,
                  fgcolor=None):
        """Return dependency graph."""
        # Use visualization settings.
        start_point_string = (
            suiterc.cfg['visualization']['initial cycle point'])

        # Use visualization settings in absence of final cycle point definition
        # when not validating (stops slowdown of validation due to vis
        # settings)
        stop_point = None
        vfcp = suiterc.cfg['visualization']['final cycle point']
        if vfcp:
            try:
                stop_point = get_point_relative(
                    vfcp, get_point(start_point_string)).standardise()
            except ValueError:
                stop_point = get_point(vfcp).standardise()

        if stop_point is not None:
            if stop_point < get_point(start_point_string):
                # Avoid a null graph.
                stop_point_string = start_point_string
            else:
                stop_point_string = str(stop_point)
        else:
            stop_point_string = None

        graph = cls(suiterc.suite, suiterc.suite_polling_tasks,
                    suiterc.cfg['visualization'])

        graph.set_def_style(fgcolor, bgcolor, graph.node_attr)

        gr_edges = suiterc.get_graph_raw(start_point_string, stop_point_string,
                                         group_nodes, ungroup_nodes,
                                         ungroup_recursive, group_all,
                                         ungroup_all)
        graph.add_edges(gr_edges, ignore_suicide)
        if subgraphs_on:
            graph.add_cycle_point_subgraphs(gr_edges, fgcolor)
        return graph
Example #7
0
    def get_point(self, point):
        """Return the point of the output to which this TaskTrigger pertains.

        Args:
            point (cylc.cycling.PointBase): The cycle point of the dependent
                task.

        Returns:
            cylc.cycling.PointBase: The cycle point of the dependency.

        """
        if self.abs_cycle_point:
            point = self.abs_cycle_point
        elif self.cycle_point_offset:
            point = get_point_relative(self.cycle_point_offset, point)
        return point
Example #8
0
    def get_message(self, point):
        """Return a string used to identify this trigger internally.

        Args:
            point (cylc.cycling.PointBase): The cycle point of the dependent
                task to which this trigger applies.

        Returns:
            str

        """
        if self.abs_cycle_point:
            point = self.abs_cycle_point
        elif self.cycle_point_offset:
            point = get_point_relative(
                self.cycle_point_offset, point)
        return '%s.%s %s' % (self.task_name, point, self.qualifier)
Example #9
0
    def get_point(self, point):
        """Return the point of the output to which this TaskTrigger pertains.

        Args:
            point (cylc.cycling.PointBase): The cycle point of the dependent
                task.

        Returns:
            cylc.cycling.PointBase: The cycle point of the dependency.

        """
        if self.abs_cycle_point:
            point = self.abs_cycle_point
        elif self.cycle_point_offset:
            point = get_point_relative(
                self.cycle_point_offset, point)
        return point
Example #10
0
    def get_prerequisite(self, point, tdef):
        """Generate a Prerequisite object from this dependency.

        Args:
            point (cylc.cycling.PointBase): The cycle point at which to
                generate the Prerequisite for.
            tdef (cylc.taskdef.TaskDef): The TaskDef of the dependent task.

        Returns:
            cylc.prerequisite.Prerequisite

        """
        # Create Prerequisite.
        cpre = Prerequisite(point, tdef.start_point)

        # Loop over TaskTrigger instances.
        for task_trigger in self.task_triggers:
            if task_trigger.cycle_point_offset is not None:
                # Inter-cycle trigger - compute the trigger's cycle point from
                # its offset.
                prereq_offset_point = get_point_relative(
                    task_trigger.cycle_point_offset, point)
                if prereq_offset_point > point:
                    # Update tdef.max_future_prereq_offset.
                    prereq_offset = prereq_offset_point - point
                    if (tdef.max_future_prereq_offset is None or
                            (prereq_offset >
                             tdef.max_future_prereq_offset)):
                        tdef.max_future_prereq_offset = (
                            prereq_offset)
                pre_initial = ((prereq_offset_point < tdef.start_point) &
                               (point >= tdef.start_point))
                cpre.add(task_trigger.task_name,
                         task_trigger.get_point(point),
                         task_trigger.output,
                         pre_initial)
            else:
                # Trigger is within the same cycle point.
                # Register task message with Prerequisite object.
                cpre.add(task_trigger.task_name,
                         task_trigger.get_point(point),
                         task_trigger.output)
        cpre.set_condition(self.get_expression(point))
        return cpre
Example #11
0
    def get_prerequisite(self, point, tdef):
        """Generate a Prerequisite object from this dependency.

        Args:
            point (cylc.cycling.PointBase): The cycle point at which to
                generate the Prerequisite for.
            tdef (cylc.taskdef.TaskDef): The TaskDef of the dependent task.

        Returns:
            cylc.prerequisite.Prerequisite

        """
        # Create Prerequisite.
        cpre = Prerequisite(point, tdef.start_point)

        # Loop over TaskTrigger instances.
        for task_trigger in self.task_triggers:
            if task_trigger.cycle_point_offset is not None:
                # Inter-cycle trigger - compute the trigger's cycle point from
                # its offset.
                prereq_offset_point = get_point_relative(
                    task_trigger.cycle_point_offset, point)
                if prereq_offset_point > point:
                    # Update tdef.max_future_prereq_offset.
                    prereq_offset = prereq_offset_point - point
                    if (tdef.max_future_prereq_offset is None or
                            (prereq_offset >
                             tdef.max_future_prereq_offset)):
                        tdef.max_future_prereq_offset = (
                            prereq_offset)
                pre_initial = ((prereq_offset_point < tdef.start_point) &
                               (point >= tdef.start_point))
                cpre.add(task_trigger.task_name,
                         task_trigger.get_point(point),
                         task_trigger.output,
                         pre_initial)
            else:
                # Trigger is within the same cycle point.
                # Register task message with Prerequisite object.
                cpre.add(task_trigger.task_name,
                         task_trigger.get_point(point),
                         task_trigger.output)
        cpre.set_condition(self.get_expression(point))
        return cpre
Example #12
0
    def get_graph(
            cls, suiterc, group_nodes=None, ungroup_nodes=None,
            ungroup_recursive=False, group_all=False, ungroup_all=False,
            ignore_suicide=False, subgraphs_on=False):
        """Return dependency graph."""
        # Use visualization settings.
        start_point_string = (
            suiterc.cfg['visualization']['initial cycle point'])

        # Use visualization settings in absence of final cycle point definition
        # when not validating (stops slowdown of validation due to vis
        # settings)
        stop_point = None
        vfcp = suiterc.cfg['visualization']['final cycle point']
        if vfcp:
            try:
                stop_point = get_point_relative(
                    vfcp, get_point(start_point_string)).standardise()
            except ValueError:
                stop_point = get_point(vfcp).standardise()

        if stop_point is not None:
            if stop_point < get_point(start_point_string):
                # Avoid a null graph.
                stop_point_string = start_point_string
            else:
                stop_point_string = str(stop_point)
        else:
            stop_point_string = None

        graph = cls(
            suiterc.suite,
            suiterc.suite_polling_tasks,
            suiterc.cfg['visualization'])
        gr_edges = suiterc.get_graph_raw(
            start_point_string, stop_point_string,
            group_nodes, ungroup_nodes, ungroup_recursive,
            group_all, ungroup_all)
        graph.add_edges(gr_edges, ignore_suicide)
        if subgraphs_on:
            graph.add_cycle_point_subgraphs(gr_edges)
        return graph
Example #13
0
    def get_cleanup_cutoff_point(cls, my_point, offset_sequence_tuples):
        """Extract the max dependent cycle point for this point."""
        if not offset_sequence_tuples:
            # This task does not have dependent tasks at other cycles.
            return my_point
        cutoff_points = []
        for offset_string, sequence in offset_sequence_tuples:
            if offset_string is None:
                # This indicates a dependency that lasts for the whole run.
                return None
            if sequence is None:
                # This indicates a simple offset interval such as [-PT6H].
                cutoff_points.append(my_point - get_interval(offset_string))
                continue
            # This is a complicated offset like [02T00-P1W].
            dependent_point = sequence.get_start_point()

            matching_dependent_points = []
            while dependent_point is not None:
                # TODO: Is it realistically possible to hang in this loop?
                target_point = (get_point_relative(offset_string,
                                                   dependent_point))
                if target_point > my_point:
                    # Assume monotonic (target_point can never jump back).
                    break
                if target_point == my_point:
                    # We have found a dependent_point for my_point.
                    matching_dependent_points.append(dependent_point)
                dependent_point = sequence.get_next_point_on_sequence(
                    dependent_point)
            if matching_dependent_points:
                # Choose the largest of the dependent points.
                cutoff_points.append(matching_dependent_points[-1])
        if cutoff_points:
            max_cutoff_point = max(cutoff_points)
            if max_cutoff_point < my_point:
                # This is caused by future triggers - default to my_point.
                return my_point
            return max_cutoff_point
        # There aren't any dependent tasks in other cycles for my_point.
        return my_point