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
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)
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
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
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
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
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
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)
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
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
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
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