Cache counts of project changes

So that the project list page is more responsive, cache counts of
open and unreviewed changes for projects.

Change-Id: I270f4009d6c7cca9d9868a181db94f779662b643
This commit is contained in:
James E. Blair 2015-12-19 13:34:35 -08:00
parent 6ad595801d
commit dc960b0cda
5 changed files with 34 additions and 8 deletions

View File

@ -185,6 +185,22 @@ class BackgroundBrowser(webbrowser.GenericBrowser):
except OSError: except OSError:
return False return False
class ProjectCache(object):
def __init__(self):
self.projects = {}
def get(self, project):
if project.key not in self.projects:
self.projects[project.key] = dict(
unreviewed_changes = len(project.unreviewed_changes),
open_changes = len(project.open_changes),
)
return self.projects[project.key]
def clear(self, project):
if project.key in self.projects:
del self.projects[project.key]
class App(object): class App(object):
simple_change_search = re.compile('^(\d+|I[a-fA-F0-9]{40})$') simple_change_search = re.compile('^(\d+|I[a-fA-F0-9]{40})$')
@ -216,6 +232,7 @@ class App(object):
self.log = logging.getLogger('gertty.App') self.log = logging.getLogger('gertty.App')
self.log.debug("Starting") self.log.debug("Starting")
self.project_cache = ProjectCache()
self.ring = mywid.KillRing() self.ring = mywid.KillRing()
self.input_buffer = [] self.input_buffer = []
webbrowser.register('xdg-open', None, BackgroundBrowser("xdg-open")) webbrowser.register('xdg-open', None, BackgroundBrowser("xdg-open"))
@ -668,6 +685,7 @@ class App(object):
message_key = draft_message.key message_key = draft_message.key
if upload: if upload:
change.reviewed = True change.reviewed = True
self.project_cache.clear(change.project)
if submit: if submit:
change.status = 'SUBMITTED' change.status = 'SUBMITTED'
change.pending_status = True change.pending_status = True

View File

@ -571,6 +571,7 @@ class SyncChangeTask(Task):
result = ChangeAddedEvent(change) result = ChangeAddedEvent(change)
else: else:
result = ChangeUpdatedEvent(change) result = ChangeUpdatedEvent(change)
app.project_cache.clear(change.project)
self.results.append(result) self.results.append(result)
change.owner = account change.owner = account
if change.status != remote_change['status']: if change.status != remote_change['status']:
@ -829,6 +830,7 @@ class SyncChangeTask(Task):
if change.reviewed: if change.reviewed:
change.reviewed = False change.reviewed = False
result.review_flag_changed = True result.review_flag_changed = True
app.project_cache.clear(change.project)
for url, refs in fetches.items(): for url, refs in fetches.items():
self.log.debug("Fetching from %s with refs %s", url, refs) self.log.debug("Fetching from %s with refs %s", url, refs)
try: try:

View File

@ -772,11 +772,13 @@ class ChangeView(urwid.WidgetWrap):
with self.app.db.getSession() as session: with self.app.db.getSession() as session:
change = session.getChange(self.change_key) change = session.getChange(self.change_key)
change.reviewed = not change.reviewed change.reviewed = not change.reviewed
self.app.project_cache.clear(change.project)
def toggleHidden(self): def toggleHidden(self):
with self.app.db.getSession() as session: with self.app.db.getSession() as session:
change = session.getChange(self.change_key) change = session.getChange(self.change_key)
change.hidden = not change.hidden change.hidden = not change.hidden
self.app.project_cache.clear(change.project)
def toggleStarred(self): def toggleStarred(self):
with self.app.db.getSession() as session: with self.app.db.getSession() as session:

View File

@ -390,6 +390,7 @@ class ChangeListView(urwid.WidgetWrap):
with self.app.db.getSession() as session: with self.app.db.getSession() as session:
change = session.getChange(change_key) change = session.getChange(change_key)
change.reviewed = not change.reviewed change.reviewed = not change.reviewed
self.app.project_cache.clear(change.project)
ret = change.reviewed ret = change.reviewed
reviewed_str = 'reviewed' if change.reviewed else 'unreviewed' reviewed_str = 'reviewed' if change.reviewed else 'unreviewed'
self.log.debug("Set change %s to %s", change_key, reviewed_str) self.log.debug("Set change %s to %s", change_key, reviewed_str)

View File

@ -41,9 +41,10 @@ class ProjectRow(urwid.Button):
name = ' '+name name = ' '+name
self.name.set_text(name) self.name.set_text(name)
def __init__(self, project, topic, callback=None): def __init__(self, app, project, topic, callback=None):
super(ProjectRow, self).__init__('', on_press=callback, super(ProjectRow, self).__init__('', on_press=callback,
user_data=(project.key, project.name)) user_data=(project.key, project.name))
self.app = app
self.mark = False self.mark = False
self._style = None self._style = None
self.project_key = project.key self.project_key = project.key
@ -67,8 +68,9 @@ class ProjectRow(urwid.Button):
self.update(project) self.update(project)
def update(self, project): def update(self, project):
cache = self.app.project_cache.get(project)
if project.subscribed: if project.subscribed:
if len(project.unreviewed_changes) > 0: if cache['unreviewed_changes'] > 0:
style = 'unreviewed-project' style = 'unreviewed-project'
else: else:
style = 'subscribed-project' style = 'subscribed-project'
@ -78,8 +80,8 @@ class ProjectRow(urwid.Button):
if self.mark: if self.mark:
style = 'marked-project' style = 'marked-project'
self.row_style.set_attr_map({None: style}) self.row_style.set_attr_map({None: style})
self.unreviewed_changes.set_text('%i ' % len(project.unreviewed_changes)) self.unreviewed_changes.set_text('%i ' % cache['unreviewed_changes'])
self.open_changes.set_text('%i ' % len(project.open_changes)) self.open_changes.set_text('%i ' % cache['open_changes'])
def toggleMark(self): def toggleMark(self):
self.mark = not self.mark self.mark = not self.mark
@ -247,7 +249,7 @@ class ProjectListView(urwid.WidgetWrap):
break break
self._deleteRow(current_row) self._deleteRow(current_row)
if not row: if not row:
row = ProjectRow(project, topic, self.onSelect) row = ProjectRow(self.app, project, topic, self.onSelect)
self.listbox.body.insert(i, row) self.listbox.body.insert(i, row)
self.project_rows[key] = row self.project_rows[key] = row
else: else:
@ -293,12 +295,13 @@ class ProjectListView(urwid.WidgetWrap):
topic_open = 0 topic_open = 0
for project in topic.projects: for project in topic.projects:
#self.log.debug(" project: %s" % project.name) #self.log.debug(" project: %s" % project.name)
topic_unreviewed += len(project.unreviewed_changes) cache = self.app.project_cache.get(project)
topic_open += len(project.open_changes) topic_unreviewed += cache['unreviewed_changes']
topic_open += cache['open_changes']
if self.subscribed: if self.subscribed:
if not project.subscribed: if not project.subscribed:
continue continue
if self.unreviewed and not project.unreviewed_changes: if self.unreviewed and not cache['unreviewed_changes']:
continue continue
if topic.key in self.open_topics: if topic.key in self.open_topics:
i = self._projectRow(i, project, topic) i = self._projectRow(i, project, topic)