def __init__(self, app): super(Updater, self).__init__() self.quit = False self.app_window = app.window self.cfg = app.cfg self.info_bar = app.info_bar self._summary_update_time = None self.err_log_lines = [] self._err_num_log_lines = 10 self.err_log_size = 0 self.task_list = [] self.state_summary = {} self.full_state_summary = {} self.fam_state_summary = {} self.full_fam_state_summary = {} self.all_families = {} self.triggering_families = {} self.global_summary = {} self.daemon_version = None self.stop_summary = None self.ancestors = {} self.ancestors_pruned = {} self.descendants = {} self.mode = "waiting..." self.update_time_str = "waiting..." self.status = SUITE_STATUS_NOT_CONNECTED self.is_reloading = False self.connected = False self._no_update_event = threading.Event() self.connect_schd = ConnectSchd() self.last_update_time = time() self.ns_defn_order = [] self.dict_ns_defn_order = {} self.restricted_display = app.restricted_display self.filter_name_string = '' self.filter_states_excl = [] self.kept_task_ids = set() self.filt_task_ids = set() self.connect_fail_warned = False self.version_mismatch_warned = False client_args = (self.cfg.suite, self.cfg.owner, self.cfg.host, self.cfg.pyro_timeout, self.cfg.port, self.cfg.db, self.cfg.my_uuid) self.state_summary_client = StateSummaryClient(*client_args) self.suite_info_client = SuiteInfoClient(*client_args) self.suite_log_client = SuiteLogClient(*client_args) self.suite_command_client = SuiteCommandClient(*client_args) # Report sign-out on exit. atexit.register(self.state_summary_client.signout)
def __init__(self, cfg, info_bar, restricted_display): super(Updater, self).__init__() self.quit = False self.cfg = cfg self.info_bar = info_bar self._summary_update_time = None self.err_log_lines = [] self._err_num_log_lines = 10 self.err_log_size = 0 self.task_list = [] self.clear_data() self.daemon_version = None self.stop_summary = None self.ancestors = {} self.ancestors_pruned = {} self.descendants = {} self.mode = "waiting..." self.dt = "waiting..." self.dt_date = None self.status = None self.connected = False self._no_update_event = threading.Event() self.poll_schd = PollSchd() self._flag_new_update() self.ns_defn_order = [] self.dict_ns_defn_order = {} self.restricted_display = restricted_display self.filter_name_string = '' self.filter_states_excl = [] self.kept_task_ids = set() self.filt_task_ids = set() self.connect_fail_warned = False self.version_mismatch_warned = False client_args = (self.cfg.suite, self.cfg.owner, self.cfg.host, self.cfg.pyro_timeout, self.cfg.port, self.cfg.db, self.cfg.my_uuid) self.state_summary_client = StateSummaryClient(*client_args) self.suite_info_client = SuiteInfoClient(*client_args) self.suite_log_client = SuiteLogClient(*client_args) self.suite_command_client = SuiteCommandClient(*client_args) # Report sign-out on exit. atexit.register(self.state_summary_client.signout)
class Updater(threading.Thread): """Retrieve information about the running or stopped suite.""" def __init__(self, app): super(Updater, self).__init__() self.quit = False self.app_window = app.window self.cfg = app.cfg self.info_bar = app.info_bar self._summary_update_time = None self.err_log_lines = [] self._err_num_log_lines = 10 self.err_log_size = 0 self.task_list = [] self.clear_data() self.daemon_version = None self.stop_summary = None self.ancestors = {} self.ancestors_pruned = {} self.descendants = {} self.mode = "waiting..." self.dt = "waiting..." self.dt_date = None self.status = None self.connected = False self._no_update_event = threading.Event() self.poll_schd = PollSchd() self._flag_new_update() self.ns_defn_order = [] self.dict_ns_defn_order = {} self.restricted_display = app.restricted_display self.filter_name_string = '' self.filter_states_excl = [] self.kept_task_ids = set() self.filt_task_ids = set() self.connect_fail_warned = False self.version_mismatch_warned = False client_args = (self.cfg.suite, self.cfg.owner, self.cfg.host, self.cfg.pyro_timeout, self.cfg.port, self.cfg.db, self.cfg.my_uuid) self.state_summary_client = StateSummaryClient(*client_args) self.suite_info_client = SuiteInfoClient(*client_args) self.suite_log_client = SuiteLogClient(*client_args) self.suite_command_client = SuiteCommandClient(*client_args) # Report sign-out on exit. atexit.register(self.state_summary_client.signout) def _flag_new_update(self): self.last_update_time = time() def reconnect(self): """Try to reconnect to the suite daemon.""" if cylc.flags.debug: print >> sys.stderr, " reconnection...", # Reset Pyro clients. self.suite_log_client.reset() self.state_summary_client.reset() self.suite_info_client.reset() self.suite_command_client.reset() try: self.daemon_version = self.suite_info_client.get_info( 'get_cylc_version') except KeyError: self.daemon_version = "??? (pre 6.1.2?)" if cylc.flags.debug: print >> sys.stderr, "succeeded (old daemon)" except PortFileError as exc: # Failed to (re)connect. # Probably normal shutdown; get a stop summary if available. if not self.connect_fail_warned: self.connect_fail_warned = True gobject.idle_add(self.warn, str(exc)) if self.stop_summary is None: self.stop_summary = get_stop_state_summary( self.cfg.suite, self.cfg.owner, self.cfg.host) self._flag_new_update() if self.stop_summary is not None and any(self.stop_summary): gobject.idle_add( self.info_bar.set_stop_summary, self.stop_summary) return except Exception as exc: if cylc.flags.debug: print >> sys.stderr, "failed: %s" % str(exc) if not self.connect_fail_warned: self.connect_fail_warned = True if isinstance(exc, Pyro.errors.ConnectionDeniedError): gobject.idle_add( self.warn, "ERROR: %s\n\nIncorrect suite passphrase?" % exc) else: gobject.idle_add(self.warn, str(exc)) return self.app_window.set_title("%s - %s:%d" % ( self.cfg.suite, self.suite_info_client.host, self.suite_info_client.port)) if cylc.flags.debug: print >> sys.stderr, "succeeded" # Connected. self.connected = True self.set_status("connected") self.connect_fail_warned = False self.poll_schd.stop() if cylc.flags.debug: print >> sys.stderr, ( "succeeded: daemon v %s" % self.daemon_version) if (self.daemon_version != CYLC_VERSION and not self.version_mismatch_warned): # (warn only once - reconnect() will be called multiple times # during initialisation of daemons at <= 6.4.0 (for which the state # summary object is not connected until all tasks are loaded). gobject.idle_add( self.warn, "Warning: cylc version mismatch!\n\n" + "Suite running with %r.\n" % self.daemon_version + "gcylc at %r.\n" % CYLC_VERSION) self.version_mismatch_warned = True self.stop_summary = None self.err_log_lines = [] self.err_log_size = 0 self._flag_new_update() def set_update(self, should_update): if should_update: self._no_update_event.clear() else: self._no_update_event.set() def retrieve_err_log(self): """Retrieve suite err log; return True if it has changed.""" try: new_err_content, new_err_size = ( self.suite_log_client.get_err_content( self.err_log_size, self._err_num_log_lines)) except AttributeError: # TODO: post-backwards compatibility concerns, remove this handling new_err_content = "" new_err_size = self.err_log_size err_log_changed = (new_err_size != self.err_log_size) if err_log_changed: self.err_log_lines += new_err_content.splitlines() self.err_log_lines = self.err_log_lines[-self._err_num_log_lines:] self.err_log_size = new_err_size return err_log_changed def retrieve_summary_update_time(self): """Retrieve suite summary update time; return True if changed.""" do_update = False try: summary_update_time = ( self.state_summary_client.get_suite_state_summary_update_time() ) if (summary_update_time is None or self._summary_update_time is None or summary_update_time != self._summary_update_time): self._summary_update_time = summary_update_time do_update = True except AttributeError as e: # TODO: post-backwards compatibility concerns, remove this handling # Force an update for daemons using the old API do_update = True return do_update def retrieve_state_summaries(self): glbl, states, fam_states = ( self.state_summary_client.get_suite_state_summary()) self.ancestors = self.suite_info_client.get_info( 'get_first_parent_ancestors') self.ancestors_pruned = self.suite_info_client.get_info( 'get_first_parent_ancestors', True) self.descendants = self.suite_info_client.get_info( 'get_first_parent_descendants') self.all_families = self.suite_info_client.get_info('get_all_families') self.triggering_families = self.suite_info_client.get_info( 'get_triggering_families') self.mode = glbl['run_mode'] if self.cfg.use_defn_order and 'namespace definition order' in glbl: # (protect for compat with old suite daemons) nsdo = glbl['namespace definition order'] if self.ns_defn_order != nsdo: self.ns_defn_order = nsdo self.dict_ns_defn_order = dict(zip(nsdo, range(0, len(nsdo)))) try: self.dt = get_time_string_from_unix_time(glbl['last_updated']) except (TypeError, ValueError): # Older suite... self.dt = glbl['last_updated'].isoformat() self.global_summary = glbl if self.restricted_display: states = self.filter_for_restricted_display(states) self.full_state_summary = states self.full_fam_state_summary = fam_states self.refilter() # Prioritise which suite state string to display. # 1. Are we stopping, or some variant of 'running'? if glbl['stopping']: self.status = 'stopping' elif glbl['will_pause_at']: self.status = 'running to hold at ' + glbl['will_pause_at'] elif glbl['will_stop_at']: self.status = 'running to ' + glbl['will_stop_at'] else: self.status = 'running' # 2. Override with temporary held status. if glbl['paused']: self.status = 'held' # 3. Override running or held with reloading. if not self.status == 'stopping': try: if glbl['reloading']: self.status = 'reloading' except KeyError: # Back compat. pass def set_stopped(self): self.connected = False self.set_status("stopped") self.poll_schd.start() self._summary_update_time = None self.clear_data() def set_status(self, status): self.status = status self.info_bar.set_status(self.status) def clear_data(self): self.state_summary = {} self.full_state_summary = {} self.fam_state_summary = {} self.full_fam_state_summary = {} self.all_families = {} self.triggering_families = {} self.global_summary = {} def warn(self, msg): """Pop up a warning dialog; call on idle_add!""" warning_dialog(msg, self.info_bar.get_toplevel()).warn() return False def update(self): if cylc.flags.debug: print >> sys.stderr, "UPDATE", ctime().split()[3], if not self.connected: # Only reconnect via self.reconnect(). self.reconnect() if cylc.flags.debug: print >> sys.stderr, "(not connected)" return False if cylc.flags.debug: print >> sys.stderr, "(connected)" try: err_log_changed = self.retrieve_err_log() summaries_changed = self.retrieve_summary_update_time() if summaries_changed: self.retrieve_state_summaries() except SuiteStillInitialisingError: # Connection achieved but state summary data not available yet. if cylc.flags.debug: print >> sys.stderr, " connected, suite initializing ..." self.set_status("initialising") if self.info_bar.prog_bar_can_start(): gobject.idle_add( self.info_bar.prog_bar_start, "suite initialising...") self.info_bar.set_state([]) return False except Pyro.errors.NamingError as exc: if self.daemon_version is not None: # Back compat <= 6.4.0 the state summary object was not # connected to Pyro until initialisation was completed. if cylc.flags.debug: print >> sys.stderr, ( " daemon <= 6.4.0, suite initializing ...") self.set_status("initialising") if self.info_bar.prog_bar_can_start(): gobject.idle_add( self.info_bar.prog_bar_start, "suite initialising...") self.info_bar.set_state([]) # Reconnect till we get the suite state object. self.reconnect() return False else: if cylc.flags.debug: print >> sys.stderr, " CONNECTION LOST", str(exc) self.set_stopped() if self.info_bar.prog_bar_active(): gobject.idle_add(self.info_bar.prog_bar_stop) self.reconnect() return False except Exception as exc: if self.status == "stopping": # Expected stop: prevent the reconnection warning dialog. self.connect_fail_warned = True if cylc.flags.debug: print >> sys.stderr, " CONNECTION LOST", str(exc) self.set_stopped() if self.info_bar.prog_bar_active(): gobject.idle_add(self.info_bar.prog_bar_stop) self.reconnect() return False else: # Got suite data. self.version_mismatch_warned = False if (self.status == "stopping" and self.info_bar.prog_bar_can_start()): gobject.idle_add( self.info_bar.prog_bar_start, "suite stopping...") if (self.status == "reloading" and self.info_bar.prog_bar_can_start()): gobject.idle_add( self.info_bar.prog_bar_start, "suite reloading...") if (self.info_bar.prog_bar_active() and self.status not in ["stopping", "initialising", "reloading"]): gobject.idle_add(self.info_bar.prog_bar_stop) if summaries_changed or err_log_changed: return True else: return False def filter_by_name(self, states): return dict( (i, j) for i, j in states.items() if self.filter_name_string in j['name'] or re.search(self.filter_name_string, j['name'])) def filter_by_state(self, states): return dict( (i, j) for i, j in states.items() if j['state'] not in self.filter_states_excl) def filter_families(self, families): """Remove family summaries if no members are present.""" # TODO - IS THERE ANY NEED TO DO THIS? fam_states = {} for fam_id, summary in families.items(): name, point_string = TaskID.split(fam_id) remove = True for mem in self.descendants[name]: mem_id = TaskID.get(mem, point_string) if mem_id in self.state_summary: remove = False break if not remove: fam_states[fam_id] = summary return fam_states def filter_for_restricted_display(self, states): return dict( (i, j) for i, j in states.items() if j['state'] in task_state.legal_for_restricted_monitoring) def refilter(self): """filter from the full state summary""" if self.filter_name_string or self.filter_states_excl: states = self.full_state_summary all_ids = set(states.keys()) if self.filter_name_string: states = self.filter_by_name(states) if self.filter_states_excl: states = self.filter_by_state(states) filtered_tasks = set(states.keys()) self.state_summary = states fam_states = self.full_fam_state_summary self.fam_state_summary = self.filter_families(fam_states) self.kept_task_ids = set(states.keys()) self.filt_task_ids = all_ids - self.kept_task_ids else: self.state_summary = self.full_state_summary self.fam_state_summary = self.full_fam_state_summary self.filt_task_ids = set() self.kept_task_ids = set(self.state_summary.keys()) self.task_list = list( set([t['name'] for t in self.state_summary.values()])) self.task_list.sort() def update_globals(self): self.info_bar.set_state(self.global_summary.get("states", [])) self.info_bar.set_mode(self.mode) self.info_bar.set_time(self.dt) self.info_bar.set_status(self.status) self.info_bar.set_log("\n".join(self.err_log_lines), self.err_log_size) return False def stop(self): self.quit = True def run(self): while not self.quit: if (not self._no_update_event.is_set() and self.poll_schd.ready() and self.update()): self._flag_new_update() gobject.idle_add(self.update_globals) sleep(1) else: pass
class Updater(threading.Thread): """Retrieve information about the running or stopped suite.""" def __init__(self, app): super(Updater, self).__init__() self.quit = False self.app_window = app.window self.cfg = app.cfg self.info_bar = app.info_bar self._summary_update_time = None self.err_log_lines = [] self._err_num_log_lines = 10 self.err_log_size = 0 self.task_list = [] self.state_summary = {} self.full_state_summary = {} self.fam_state_summary = {} self.full_fam_state_summary = {} self.all_families = {} self.triggering_families = {} self.global_summary = {} self.daemon_version = None self.stop_summary = None self.ancestors = {} self.ancestors_pruned = {} self.descendants = {} self.mode = "waiting..." self.update_time_str = "waiting..." self.status = SUITE_STATUS_NOT_CONNECTED self.is_reloading = False self.connected = False self._no_update_event = threading.Event() self.connect_schd = ConnectSchd() self.last_update_time = time() self.ns_defn_order = [] self.dict_ns_defn_order = {} self.restricted_display = app.restricted_display self.filter_name_string = '' self.filter_states_excl = [] self.kept_task_ids = set() self.filt_task_ids = set() self.connect_fail_warned = False self.version_mismatch_warned = False client_args = (self.cfg.suite, self.cfg.owner, self.cfg.host, self.cfg.pyro_timeout, self.cfg.port, self.cfg.db, self.cfg.my_uuid) self.state_summary_client = StateSummaryClient(*client_args) self.suite_info_client = SuiteInfoClient(*client_args) self.suite_log_client = SuiteLogClient(*client_args) self.suite_command_client = SuiteCommandClient(*client_args) # Report sign-out on exit. atexit.register(self.state_summary_client.signout) def reconnect(self): """Try to reconnect to the suite daemon.""" if cylc.flags.debug: print >> sys.stderr, " reconnection...", # Reset Pyro clients. self.suite_log_client.reset() self.state_summary_client.reset() self.suite_info_client.reset() self.suite_command_client.reset() try: self.daemon_version = self.suite_info_client.get_info( 'get_cylc_version') except KeyError: self.daemon_version = "??? (pre 6.1.2?)" if cylc.flags.debug: print >> sys.stderr, "succeeded (old daemon)" except PortFileError as exc: if cylc.flags.debug: traceback.print_exc() # Failed to (re)connect. # Probably normal shutdown; get a stop summary if available. if not self.connect_fail_warned: self.connect_fail_warned = True gobject.idle_add(self.warn, str(exc)) if self.cfg.suite and self.stop_summary is None: self.stop_summary = get_stop_state_summary( cat_state(self.cfg.suite, self.cfg.host, self.cfg.owner)) self.last_update_time = time() if self.stop_summary is not None and any(self.stop_summary): gobject.idle_add(self.info_bar.set_stop_summary, self.stop_summary) else: self.info_bar.set_update_time(None, self.info_bar.DISCONNECTED_TEXT) return except Pyro.errors.NamingError as exc: if cylc.flags.debug: traceback.print_exc() return except Exception as exc: if cylc.flags.debug: traceback.print_exc() if not self.connect_fail_warned: self.connect_fail_warned = True if isinstance(exc, Pyro.errors.ConnectionDeniedError): gobject.idle_add( self.warn, "ERROR: %s\n\nIncorrect suite passphrase?" % exc) else: gobject.idle_add(self.warn, str(exc)) return gobject.idle_add( self.app_window.set_title, "%s - %s:%s" % (self.cfg.suite, self.suite_info_client.host, self.suite_info_client.port)) if cylc.flags.debug: print >> sys.stderr, "succeeded" # Connected. self.connected = True # This status will be very transient: self.set_status(SUITE_STATUS_CONNECTED) self.connect_fail_warned = False self.connect_schd.stop() if cylc.flags.debug: print >> sys.stderr, ("succeeded: daemon v %s" % self.daemon_version) if (self.daemon_version != CYLC_VERSION and not self.version_mismatch_warned): # (warn only once - reconnect() will be called multiple times # during initialisation of daemons at <= 6.4.0 (for which the state # summary object is not connected until all tasks are loaded). gobject.idle_add( self.warn, "Warning: cylc version mismatch!\n\n" + "Suite running with %r.\n" % self.daemon_version + "gcylc at %r.\n" % CYLC_VERSION) self.version_mismatch_warned = True self.stop_summary = None self.err_log_lines = [] self.err_log_size = 0 self.last_update_time = time() def set_update(self, should_update): """Set update flag.""" if should_update: self._no_update_event.clear() else: self._no_update_event.set() def retrieve_err_log(self): """Retrieve suite err log; return True if it has changed.""" try: new_err_content, new_err_size = ( self.suite_log_client.get_err_content(self.err_log_size, self._err_num_log_lines)) except AttributeError: # TODO: post-backwards compatibility concerns, remove this handling new_err_content = "" new_err_size = self.err_log_size err_log_changed = (new_err_size != self.err_log_size) if err_log_changed: self.err_log_lines += new_err_content.splitlines() self.err_log_lines = self.err_log_lines[-self._err_num_log_lines:] self.err_log_size = new_err_size return err_log_changed def retrieve_summary_update_time(self): """Retrieve suite summary update time; return True if changed.""" do_update = False try: summary_update_time = (self.state_summary_client. get_suite_state_summary_update_time()) if (summary_update_time is None or self._summary_update_time is None or summary_update_time != self._summary_update_time): self._summary_update_time = summary_update_time do_update = True except AttributeError: # TODO: post-backwards compatibility concerns, remove this handling # Force an update for daemons using the old API do_update = True return do_update def retrieve_state_summaries(self): """Retrieve suite summary.""" glbl, states, fam_states = ( self.state_summary_client.get_suite_state_summary()) self.ancestors = self.suite_info_client.get_info( 'get_first_parent_ancestors') self.ancestors_pruned = self.suite_info_client.get_info( 'get_first_parent_ancestors', True) self.descendants = self.suite_info_client.get_info( 'get_first_parent_descendants') self.all_families = self.suite_info_client.get_info('get_all_families') self.triggering_families = self.suite_info_client.get_info( 'get_triggering_families') self.mode = glbl['run_mode'] if self.cfg.use_defn_order and 'namespace definition order' in glbl: # (protect for compat with old suite daemons) nsdo = glbl['namespace definition order'] if self.ns_defn_order != nsdo: self.ns_defn_order = nsdo self.dict_ns_defn_order = dict(zip(nsdo, range(0, len(nsdo)))) try: self.update_time_str = get_time_string_from_unix_time( glbl['last_updated']) except (TypeError, ValueError): # Older suite... self.update_time_str = glbl['last_updated'].isoformat() self.global_summary = glbl if self.restricted_display: states = self.filter_for_restricted_display(states) self.full_state_summary = states self.full_fam_state_summary = fam_states self.refilter() try: self.status = glbl['status_string'] except KeyError: # Back compat for suite daemons <= 6.9.1. self.status = get_suite_status_string(glbl['paused'], glbl['stopping'], glbl['will_pause_at'], glbl['will_stop_at']) try: self.is_reloading = glbl['reloading'] except KeyError: # Back compat. pass def set_stopped(self): """Reset data and clients when suite is stopped.""" self.connected = False self.set_status(SUITE_STATUS_STOPPED) self.connect_schd.start() self._summary_update_time = None self.state_summary = {} self.full_state_summary = {} self.fam_state_summary = {} self.full_fam_state_summary = {} self.all_families = {} self.triggering_families = {} self.global_summary = {} self.cfg.port = None for client in [ self.state_summary_client, self.suite_info_client, self.suite_log_client, self.suite_command_client ]: if self.cfg.host is None: client.host = None client.port = None if self.cfg.host: gobject.idle_add(self.app_window.set_title, "%s - %s" % (self.cfg.suite, self.cfg.host)) else: gobject.idle_add(self.app_window.set_title, str(self.cfg.suite)) def set_status(self, status=None): """Update status bar.""" if status is not None: self.status = status self.info_bar.set_status(self.status) def warn(self, msg): """Pop up a warning dialog; call on idle_add!""" warning_dialog(msg, self.info_bar.get_toplevel()).warn() return False def update(self): """Try and connect and do an update.""" if self._no_update_event.is_set(): return False if not self.connect_schd.ready(): self.info_bar.set_update_time( None, get_seconds_as_interval_string(round( self.connect_schd.dt_next))) return False if cylc.flags.debug: print >> sys.stderr, "UPDATE %s" % get_current_time_string() if not self.connected: # Only reconnect via self.reconnect(). self.reconnect() if not self.connected: self.set_stopped() if cylc.flags.debug: print >> sys.stderr, "(not connected)" return False if cylc.flags.debug: print >> sys.stderr, "(connected)" try: err_log_changed = self.retrieve_err_log() summaries_changed = self.retrieve_summary_update_time() if summaries_changed: self.retrieve_state_summaries() except SuiteStillInitialisingError: # Connection achieved but state summary data not available yet. if cylc.flags.debug: print >> sys.stderr, " connected, suite initializing ..." self.set_status(SUITE_STATUS_INITIALISING) if self.info_bar.prog_bar_can_start(): gobject.idle_add(self.info_bar.prog_bar_start, SUITE_STATUS_INITIALISING) self.info_bar.set_state([]) return False except Pyro.errors.NamingError as exc: if self.daemon_version is not None: # Back compat <= 6.4.0 the state summary object was not # connected to Pyro until initialisation was completed. if cylc.flags.debug: print >> sys.stderr, ( " daemon <= 6.4.0, suite initializing ...") self.set_status(SUITE_STATUS_INITIALISING) if self.info_bar.prog_bar_can_start(): gobject.idle_add(self.info_bar.prog_bar_start, SUITE_STATUS_INITIALISING) self.info_bar.set_state([]) # Reconnect till we get the suite state object. self.reconnect() return False else: if cylc.flags.debug: print >> sys.stderr, " CONNECTION LOST", str(exc) self.set_stopped() if self.info_bar.prog_bar_active(): gobject.idle_add(self.info_bar.prog_bar_stop) self.reconnect() return False except Exception as exc: if self.status == SUITE_STATUS_STOPPING: # Expected stop: prevent the reconnection warning dialog. self.connect_fail_warned = True if cylc.flags.debug: print >> sys.stderr, " CONNECTION LOST", str(exc) self.set_stopped() if self.info_bar.prog_bar_active(): gobject.idle_add(self.info_bar.prog_bar_stop) self.reconnect() return False else: # Got suite data. self.version_mismatch_warned = False if (self.status == SUITE_STATUS_STOPPING and self.info_bar.prog_bar_can_start()): gobject.idle_add(self.info_bar.prog_bar_start, self.status) if (self.is_reloading and self.info_bar.prog_bar_can_start()): gobject.idle_add(self.info_bar.prog_bar_start, "reloading") if (self.info_bar.prog_bar_active() and not self.is_reloading and self.status not in [SUITE_STATUS_STOPPING, SUITE_STATUS_INITIALISING]): gobject.idle_add(self.info_bar.prog_bar_stop) if summaries_changed or err_log_changed: return True else: return False def filter_by_name(self, states): """Filter by name string.""" return dict((i, j) for i, j in states.items() if self.filter_name_string in j['name'] or re.search(self.filter_name_string, j['name'])) def filter_by_state(self, states): """Filter by state key.""" return dict((i, j) for i, j in states.items() if j['state'] not in self.filter_states_excl) def filter_families(self, families): """Remove family summaries if no members are present.""" # TODO - IS THERE ANY NEED TO DO THIS? fam_states = {} for fam_id, summary in families.items(): name, point_string = TaskID.split(fam_id) remove = True for mem in self.descendants[name]: mem_id = TaskID.get(mem, point_string) if mem_id in self.state_summary: remove = False break if not remove: fam_states[fam_id] = summary return fam_states @classmethod def filter_for_restricted_display(cls, states): """Filter for legal restricted states.""" return dict((i, j) for i, j in states.items() if j['state'] in TASK_STATUSES_RESTRICTED) def refilter(self): """filter from the full state summary""" if self.filter_name_string or self.filter_states_excl: states = self.full_state_summary all_ids = set(states.keys()) if self.filter_name_string: states = self.filter_by_name(states) if self.filter_states_excl: states = self.filter_by_state(states) self.state_summary = states fam_states = self.full_fam_state_summary self.fam_state_summary = self.filter_families(fam_states) self.kept_task_ids = set(states.keys()) self.filt_task_ids = all_ids - self.kept_task_ids else: self.state_summary = self.full_state_summary self.fam_state_summary = self.full_fam_state_summary self.filt_task_ids = set() self.kept_task_ids = set(self.state_summary.keys()) self.task_list = list( set([t['name'] for t in self.state_summary.values()])) self.task_list.sort() def update_globals(self): """Update common widgets.""" self.info_bar.set_state(self.global_summary.get("states", [])) self.info_bar.set_mode(self.mode) self.info_bar.set_update_time(self.update_time_str) self.info_bar.set_status(self.status) self.info_bar.set_log("\n".join(self.err_log_lines), self.err_log_size) return False def stop(self): """Tell self.run to exit.""" self.quit = True def run(self): """Start the thread.""" while not self.quit: if self.update(): self.last_update_time = time() gobject.idle_add(self.update_globals) sleep(1)