Skip to content

Commit

Permalink
gscan hover data now comes from SuiteIdServer.
Browse files Browse the repository at this point in the history
  • Loading branch information
oliver-sanders committed Jun 29, 2016
1 parent 20e5800 commit f308625
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 38 deletions.
55 changes: 17 additions & 38 deletions lib/cylc/gui/gscan.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,11 @@

from cylc.cfgspec.globalcfg import GLOBAL_CFG
from cylc.cfgspec.gcylc import gcfg
from cylc.exceptions import PortFileError
import cylc.flags
from cylc.gui.legend import ThemeLegendWindow
from cylc.gui.dot_maker import DotMaker
from cylc.gui.util import get_icon, setup_icons, set_exception_hook_dialog
from cylc.network.port_scan import scan_all
from cylc.network.suite_state import StateSummaryClient
from cylc.owner import USER
from cylc.version import CYLC_VERSION
from cylc.task_state import TASK_STATUSES_ORDERED, TASK_STATUS_RUNAHEAD
Expand All @@ -53,9 +51,8 @@
def get_hosts_suites_info(hosts, timeout=None, owner=None):
"""Return a dictionary of hosts, suites, and their properties."""
host_suites_map = {}
for host, port_results in scan_all(
for host, (port, result) in scan_all(
hosts=hosts, pyro_timeout=timeout):
port, result = port_results
if owner and owner != result.get(KEY_OWNER):
continue
if host not in host_suites_map:
Expand Down Expand Up @@ -950,7 +947,7 @@ def __init__(self, hosts, suite_treemodel, suite_treeview, owner=None,
poll_interval=None):
self.suite_treemodel = suite_treemodel
self.suite_treeview = suite_treeview
self.active_tasks = {}
self.tasks_by_state = {}
super(ScanAppUpdater, self).__init__(hosts, owner=owner,
poll_interval=poll_interval)

Expand Down Expand Up @@ -987,36 +984,22 @@ def clear_stopped_suites(self):
def get_last_n_tasks(self, suite, host, task_state, point_string, n):
"""Returns a list of the last 'n' tasks with the provided state for
the provided suite."""
# TODO: safety check

# Get task state summary information.
if suite + host not in self.active_tasks:
# Get list of tasks for the provided state or return an error msg.
if suite + host not in self.tasks_by_state:
return ['<i>Could not get info, try refreshing the scanner.</i>']
tasks = self.active_tasks[suite + host]
tasks = self.tasks_by_state[suite + host][task_state]
if tasks is False:
return ['<i>Cannot connect to suite.</i>']

# If point_string specified, remove entries at other point_strings.
to_remove = []
# Filter by point string if provided.
if point_string:
for task in tasks:
_, task_point_string = task.rsplit('.', 1)
if task_point_string != point_string:
to_remove.append(task)
for task in to_remove:
del tasks[task]

# Get list of tasks that match the provided state.
ret = []
for task in tasks:
if tasks[task]['state'] == task_state:
time_strings = ['1970-01-01T00:00:00Z']
for time_string in self.TIME_STRINGS:
if time_string in tasks[task] and tasks[task][time_string]:
time_strings.append(tasks[task][time_string])
ret.append((max(time_strings), task))

# return only the n youngest items
ret = [(last_timestamp, task_name + '.' + p_string) for
(last_timestamp, task_name, p_string) in tasks if
p_string == point_string]
else:
ret = [(task[0], task[1] + '.' + task[2]) for task in tasks]

# Return only the n youngest items.
ret.sort(reverse=True)
if len(ret) - n == 1:
n += 1
Expand All @@ -1038,15 +1021,7 @@ def update(self):
if (suite, host) not in suite_host_tuples:
suite_host_tuples.append((suite, host))
suite_host_tuples.sort()
self.active_tasks = {}
for suite, host in suite_host_tuples:

try:
self.active_tasks[suite + host] = StateSummaryClient(
suite, host=host).get_suite_state_summary()[1]
except PortFileError:
self.active_tasks[suite + host] = False

if suite in info.get(host, {}):
suite_info = info[host][suite]
is_stopped = False
Expand All @@ -1058,6 +1033,10 @@ def update(self):
)
title = suite_info.get("title")

if 'tasks-by-state' in suite_info:
self.tasks_by_state[suite + host] = suite_info[
'tasks-by-state']

if KEY_STATES in suite_info:
for key in sorted(suite_info):
if not key.startswith(KEY_STATES):
Expand Down
2 changes: 2 additions & 0 deletions lib/cylc/network/suite_identifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ def identify(self):
result['states'] = StateSummaryServer.get_inst().get_state_totals()
result['update-time'] = (
StateSummaryServer.get_inst().get_summary_update_time())
result['tasks-by-state'] = (
StateSummaryServer.get_inst().get_tasks_by_state())
return result

def id(self):
Expand Down
20 changes: 20 additions & 0 deletions lib/cylc/network/suite_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ class StateSummaryServer(PyroServer):
"""Server-side suite state summary interface."""

_INSTANCE = None
TIME_STRINGS = ['submitted_time_string', 'started_time_string',
'finished_time_string']

@classmethod
def get_inst(cls, run_mode=None):
Expand Down Expand Up @@ -256,6 +258,24 @@ def get_state_summary(self):
raise SuiteStillInitialisingError()
return (self.global_summary, self.task_summary, self.family_summary)

def get_tasks_by_state(self):
"""Returns a dictionary containing lists of tasks by state in the form:
{state: [(most_recent_time_string, task_name, point_string), ...]}."""
check_access_priv(self, 'state-totals')
ret = {}
for task in self.task_summary:
state = self.task_summary[task]['state']
if state not in ret:
ret[state] = []
time_strings = ['1970-01-01T00:00:00Z'] # Default time string.
for time_string in self.TIME_STRINGS:
if (time_string in self.task_summary[task] and
self.task_summary[task][time_string]):
time_strings.append(self.task_summary[task][time_string])
task_name, point_string = task.rsplit('.', 1)
ret[state].append((max(time_strings), task_name, point_string))
return ret

def get_summary_update_time(self):
"""Return the last time the summaries were changed (Unix time)."""
check_access_priv(self, 'state-totals')
Expand Down

0 comments on commit f308625

Please sign in to comment.