def expire(self, cutoff): """Clear all settings targeting cycle points earlier than cutoff.""" point_strings = [] cutoff_point = None if cutoff is not None: cutoff_point = get_point(str(cutoff)) for point_string in self.settings: if cutoff_point is None or ( point_string not in self.ALL_CYCLE_POINTS_STRS and get_point(point_string) < cutoff_point): point_strings.append(point_string) if not point_strings: return (None, {"expire": [cutoff]}) return self.clear(point_strings=point_strings)
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 expire_broadcast(self, cutoff=None): """Clear all broadcasts targeting cycle points earlier than cutoff.""" point_strings = [] cutoff_point = None if cutoff is not None: cutoff_point = get_point(str(cutoff)) with self.lock: for point_string in self.broadcasts: if cutoff_point is None or ( point_string not in self.ALL_CYCLE_POINTS_STRS and get_point(point_string) < cutoff_point): point_strings.append(point_string) if not point_strings: return (None, {"expire": [cutoff]}) return self.clear_broadcast(point_strings=point_strings)
def is_off_sequence(self, name, point, cache=None): """Return True if task <name> at point <point> is off-sequence. (This implies inter-cycle dependence on a task that will not be instantiated at run time). """ try: sequences = self.suiterc.taskdefs[name].sequences except KeyError: # Handle tasks not used in the graph. return False if not sequences: return False for sequence in sequences: p_str = str(point) if (cache and sequence in cache and p_str in cache[sequence]): if cache[sequence][p_str]: return False else: temp = sequence.is_on_sequence(get_point(point)) if cache is not None: cache.setdefault(sequence, {})[p_str] = temp if temp: return False return True
def add( self, message, label = None ): # Add a new prerequisite message in an UNSATISFIED state. if self.start_point: task = re.search( r'(.*).(.*) ', message) if task.group: try: foo = task.group().split(".")[1].rstrip() if ( get_point( foo ) < self.start_point ): return except IndexError: pass if label: pass else: self.auto_label += 1 label = str( self.auto_label ) if message in self.labels: # IGNORE A DUPLICATE PREREQUISITE (the same trigger must # occur in multiple non-conditional graph string sections). # Warnings disabled pending a global check across all # prerequisites held by a task. ##print >> sys.stderr, "WARNING, " + self.owner_id + ": duplicate prerequisite: " + message return self.messages[ label ] = message self.labels[ message ] = label self.satisfied[label] = False self.satisfied_by[label] = None m = re.match( self.__class__.CYCLE_POINT_RE, message ) if m: self.target_point_strings.append( m.groups()[0] )
def add(self, message, label=None): # Add a new prerequisite message in an UNSATISFIED state. if self.start_point: task = re.search(r'(.*).(.*) ', message) if task.group: try: foo = task.group().split(".")[1].rstrip() if (get_point(foo) < self.start_point): return except IndexError: pass if label: pass else: self.auto_label += 1 label = str(self.auto_label) if message in self.labels: # IGNORE A DUPLICATE PREREQUISITE (the same trigger must # occur in multiple non-conditional graph string sections). # Warnings disabled pending a global check across all # prerequisites held by a task. ##print >> sys.stderr, "WARNING, " + self.owner_id + ": duplicate prerequisite: " + message return self.messages[label] = message self.labels[message] = label self.satisfied[label] = False self.satisfied_by[label] = None m = re.match(self.__class__.CYCLE_POINT_RE, message) if m: self.target_point_strings.append(m.groups()[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
def set_condition(self, expr): # 'foo | bar & baz' # 'foo:fail | foo' # 'foo[T-6]:out1 | baz' drop_these = [] if hasattr(self, 'all_satisfied'): delattr(self, 'all_satisfied') if self.pre_initial_messages: for k in self.pre_initial_messages: drop_these.append(k) # Needed to drop pre warm-start dependence: for k in self.messages: if k in drop_these: continue if self.start_point: m = re.search( r'(' + TaskID.NAME_RE + ')\.(' + TaskID.POINT_RE + ') ', self.messages[k]) if m: try: foo = m.group().split(".")[1].rstrip() if (get_point(foo) < self.start_point and self.point >= self.start_point): drop_these.append(k) except IndexError: pass for label in drop_these: if self.messages.get(label): msg = self.messages[label] self.messages.pop(label) self.messages_set.remove(msg) self.satisfied.pop(label) self.labels.pop(msg) if '|' in expr: if drop_these: simpler = ConditionalSimplifier(expr, drop_these) expr = simpler.get_cleaned() # Make a Python expression so we can eval() the logic. self.raw_conditional_expression = expr for label in self.messages: expr = re.sub( r'\b' + label + r'\b', 'self.satisfied[\'' + label + '\']', expr) self.conditional_expression = expr
def set_condition( self, expr ): # 'foo | bar & baz' # 'foo:fail | foo' # 'foo[T-6]:out1 | baz' drop_these = [] for k in self.messages: if self.start_point: task = re.search( r'(.*).(.*) ', self.messages[k]) if task.group: try: foo = task.group().split(".")[1].rstrip() if ( get_point( foo ) < self.start_point and foo != '1' ): # TODO - ASYNC TASKS '1' ONLY NEEDS UPDATING FOR # INTEGER CYCLING (AND MORE?) drop_these.append(k) except IndexError: pass if self.pre_initial_messages: for k in self.pre_initial_messages: drop_these.append(k) if drop_these: simpler = conditional_simplifier(expr, drop_these) expr = simpler.get_cleaned() # make into a python expression self.raw_conditional_expression = expr for label in self.messages: # match label start and end on on word boundary expr = re.sub( r'\b' + label + r'\b', 'self.satisfied[\'' + label + '\']', expr ) for label in self.excess_labels: # treat duplicate triggers as always satisfied expr = re.sub( r'\b' + label + r'\b', 'True', expr ) self.raw_conditional_expression = re.sub( r'\b' + label + r'\b', 'True', self.raw_conditional_expression ) for label in drop_these: if self.messages.get(label): msg = self.messages[label] self.messages.pop(label) self.satisfied.pop(label) self.labels.pop(msg) self.conditional_expression = expr
def set_condition(self, expr): # 'foo | bar & baz' # 'foo:fail | foo' # 'foo[T-6]:out1 | baz' drop_these = [] if hasattr(self, 'all_satisfied'): delattr(self, 'all_satisfied') if self.pre_initial_messages: for message in self.pre_initial_messages: drop_these.append(message) # Needed to drop pre warm-start dependence: for message in self.messages: if message in drop_these: continue if self.start_point: # Extract the cycle point from the message. match = self.CYCLE_POINT_RE.search(message) if match: # Get cycle point if (get_point(match.groups()[0]) < self.start_point and self.point >= self.start_point): # Drop if outside of relevant point range. drop_these.append(message) for message in drop_these: if message in self.messages: self.messages.remove(message) self.satisfied.pop(message) if '|' in expr: if drop_these: simpler = ConditionalSimplifier(expr, drop_these) expr = simpler.get_cleaned() # Make a Python expression so we can eval() the logic. for message in self.messages: expr = expr.replace(message, self.SATISFIED_TEMPLATE % message) self.conditional_expression = expr
def set_condition(self, expr): """Set the conditional expression for this prerequisite. Resets the cached state (self._all_satisfied). """ drop_these = [] self._all_satisfied = None if self.pre_initial_messages: for message in self.pre_initial_messages: drop_these.append(message) # Needed to drop pre warm-start dependence: for message in self.satisfied: if message in drop_these: continue if self.start_point: if message[1]: # Cycle point. if (get_point(message[1]) < self.start_point and self.point >= self.start_point): # Drop if outside of relevant point range. drop_these.append(message) for message in drop_these: if message in self.satisfied: self.satisfied.pop(message) if '|' in expr: if drop_these: simpler = ConditionalSimplifier( expr, [self.MESSAGE_TEMPLATE % m for m in drop_these]) expr = simpler.get_cleaned() # Make a Python expression so we can eval() the logic. for message in self.satisfied: expr = expr.replace(self.MESSAGE_TEMPLATE % message, self.SATISFIED_TEMPLATE % message) self.conditional_expression = expr
def is_ghost_task(self, name, point, cache=None): """Returns True if the task <name> at cycle point <point> is a ghost. """ try: sequences = self.suiterc.taskdefs[name].sequences except KeyError: # Handle tasks not used in the graph. return False if not sequences: return False for sequence in sequences: p_str = str(point) if (cache and sequence in cache and p_str in cache[sequence]): if cache[sequence][p_str]: return False else: temp = sequence.is_on_sequence(get_point(point)) if cache is not None: cache.setdefault(sequence, {})[p_str] = temp if temp: return False return True
def get_target_points(self): """Return a list of cycle points target by each prerequisite, including each component of conditionals.""" return [get_point(p) for p in self.target_point_strings]
def get_target_points( self ): """Return a list of cycle points target by each prerequisite, including each component of conditionals.""" return [ get_point(p) for p in self.target_point_strings ]