Skip to content

Commit 675c652

Browse files
committed
Additional changes to speed up the IESG agenda docs page: Changed telechat_page_count() to accept a list of documents if that's already been generated, to avoid double work. Changed the reviewed_by_teams list to provide acronyms directly, to avoid group lookups during template rendering. Provided page counts directly to the template instead of repeated (costly) filtering through telechat_page_count, with new document lookups. Removed the telechat_page_count template filter, due to its cost. Tweaked some lookups in fill_in_document_table_attributes() . Added to the select_related() list for documents in IESG agenda_documents().
- Legacy-Id: 14988
1 parent 60a60de commit 675c652

9 files changed

Lines changed: 50 additions & 28 deletions

File tree

ietf/doc/forms.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def __init__(self, *args, **kwargs):
2626
self.page_count = {}
2727
choice_display = {}
2828
for d in dates:
29-
self.page_count[d] = telechat_page_count(d).for_approval
29+
self.page_count[d] = telechat_page_count(date=d).for_approval
3030
choice_display[d] = '%s (%s pages)' % (d.strftime("%Y-%m-%d"),self.page_count[d])
3131
if d-datetime.date.today() < datetime.timedelta(days=13):
3232
choice_display[d] += ' : WARNING - this may not leave enough time for directorate reviews!'

ietf/doc/utils_search.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def fill_in_document_table_attributes(docs):
4343
seen.add(e.doc_id)
4444

4545
# on agenda in upcoming meetings
46-
presentations = SessionPresentation.objects.filter(session__timeslotassignments__timeslot__time__gte=datetime.datetime.today()).distinct().select_related('session', 'document')
46+
presentations = SessionPresentation.objects.filter(session__meeting__date__gte=datetime.date.today()-datetime.timedelta(days=7)).select_related('session', 'document')
4747
session_list = [ (p.document, p.session) for p in presentations ]
4848
sessions = dict( (d, []) for (d, s) in session_list )
4949
for (d, s) in session_list:
@@ -74,9 +74,8 @@ def fill_in_document_table_attributes(docs):
7474
d.expirable = expirable_draft(d)
7575

7676
if d.get_state_slug() != "rfc":
77-
d.milestones = sorted((m for m in d.groupmilestone_set.all() if m.state_id == "active"), key=lambda m: m.time)
78-
79-
d.reviewed_by_teams = sorted(set(r.team for r in d.reviewrequest_set.filter(state__in=["requested","accepted","part-completed","completed"])), key=lambda g: g.acronym)
77+
d.milestones = [ m for (t, m) in sorted(((m.time, m) for m in d.groupmilestone_set.all() if m.state_id == "active")) ]
78+
d.reviewed_by_teams = sorted(set(r.team.acronym for r in d.reviewrequest_set.filter(state__in=["requested","accepted","part-completed","completed"]).distinct().select_related('team')))
8079

8180
d.sessions = sessions[d] if d in sessions else []
8281

ietf/iesg/templatetags/__init__.py

Whitespace-only changes.

ietf/iesg/templatetags/iesg_filters.py

Lines changed: 0 additions & 9 deletions
This file was deleted.

ietf/iesg/utils.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
from collections import namedtuple
22

3+
import debug # pyflakes:ignore
4+
35
from ietf.doc.models import Document, TelechatDocEvent, STATUSCHANGE_RELATIONS
46
from ietf.iesg.agenda import get_doc_section
57

68
TelechatPageCount = namedtuple('TelechatPageCount',['for_approval','for_action','related'])
79

8-
def telechat_page_count(date):
10+
def telechat_page_count(date=None, docs=None):
11+
if not date and not docs:
12+
return TelechatPageCount(0, 0, 0)
913

10-
candidates = Document.objects.filter(docevent__telechatdocevent__telechat_date=date).distinct()
11-
12-
docs = [ doc for doc in candidates if doc.latest_event(TelechatDocEvent,type='scheduled_for_telechat').telechat_date==date ]
14+
if not docs:
15+
candidates = Document.objects.filter(docevent__telechatdocevent__telechat_date=date).distinct()
16+
docs = [ doc for doc in candidates if doc.latest_event(TelechatDocEvent,type='scheduled_for_telechat').telechat_date==date ]
1317

1418
for_action =[d for d in docs if get_doc_section(d).endswith('.3')]
1519

ietf/iesg/views.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def agenda_json(request, date=None):
9494
res = {
9595
"telechat-date": str(data["date"]),
9696
"as-of": str(datetime.datetime.utcnow()),
97-
"page-counts": telechat_page_count(get_agenda_date(date))._asdict(),
97+
"page-counts": telechat_page_count(date=get_agenda_date(date))._asdict(),
9898
"sections": {},
9999
}
100100

@@ -358,7 +358,10 @@ def agenda_documents(request):
358358
dates = list(TelechatDate.objects.active().order_by('date').values_list("date", flat=True)[:4])
359359

360360
docs_by_date = dict((d, []) for d in dates)
361-
for doc in Document.objects.filter(docevent__telechatdocevent__telechat_date__in=dates).select_related("stream", "group").distinct():
361+
for doc in (Document.objects
362+
.filter(docevent__telechatdocevent__telechat_date__in=dates)
363+
.select_related('stream', 'group', 'intended_std_level')
364+
.distinct()):
362365
d = doc.latest_event(TelechatDocEvent, type="scheduled_for_telechat").telechat_date
363366
if d in docs_by_date:
364367
docs_by_date[d].append(doc)
@@ -379,9 +382,11 @@ def agenda_documents(request):
379382
# the search_result_row view to display them (which expects them)
380383
fill_in_document_table_attributes(docs_by_date[date])
381384
fill_in_agenda_docs(date, sections, docs_by_date[date])
385+
pages = telechat_page_count(docs=docs_by_date[date]).for_approval
382386

383387
telechats.append({
384388
"date":date,
389+
"pages":pages,
385390
"sections": sorted((num, section) for num, section in sections.iteritems()
386391
if "2" <= num < "5")
387392
})

ietf/templates/doc/search/status_columns.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@
4444

4545
{% if doc.reviewed_by_teams %}
4646
<br>Reviews:
47-
{% for g in doc.reviewed_by_teams %}
48-
{{ g.acronym }}{% if not forloop.last %}, {% endif %}
47+
{% for acronym in doc.reviewed_by_teams %}
48+
{{ acronym }}{% if not forloop.last %}, {% endif %}
4949
{% endfor %}
5050
{% endif %}
5151

ietf/templates/iesg/agenda_documents.html

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
{% load ballot_icon %}
66
{% load ietf_filters %}
7-
{% load iesg_filters %}
87

98
{% block pagehead %}
109
<link rel="alternate" type="application/atom+xml" href="/feed/iesg-agenda/">
@@ -39,10 +38,8 @@ <h1>Documents on future IESG telechat agendas</h1>
3938

4039
{% for t in telechats %}
4140
<h2>IESG telechat {{t.date}}
42-
{% with t|telechat_page_count as pages %}
43-
<small class="text-muted">{{pages}} page{{pages|pluralize}}</small>
44-
{% endwith %}
45-
</h2>
41+
<small class="text-muted">{{t.pages}} page{{t.pages|pluralize}}</small>
42+
</h2>
4643
<p>
4744
<a class="btn btn-default" role="button" href="/iesg/agenda/">
4845
<span class="fa fa-list"></span>

ietf/utils/decorators.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import datetime
44

5-
from decorator import decorator
5+
from decorator import decorator, decorate
66

77
from django.conf import settings
88
from django.contrib.auth import login
@@ -74,3 +74,29 @@ def err(code, text):
7474
PersonApiKeyEvent.objects.create(person=person, type='apikey_login', key=key, desc="Logged in with key ID %s, endpoint %s" % (key.id, key.endpoint))
7575
# Execute decorated function
7676
return f(request, *args, **kwargs)
77+
78+
79+
def _memoize(func, self, *args, **kwargs):
80+
''''Memoize wrapper for instance methouds. Use @lru_cache for functions.'''
81+
if kwargs: # frozenset is used to ensure hashability
82+
key = args, frozenset(kwargs.items())
83+
else:
84+
key = args
85+
# instance method, set up cache if needed
86+
if not hasattr(self, '_cache'):
87+
self._cache = {}
88+
if not func in self._cache:
89+
self._cache[func] = {}
90+
#
91+
cache = self._cache[func]
92+
if key not in cache:
93+
cache[key] = func(self, *args, **kwargs)
94+
return cache[key]
95+
def memoize(func):
96+
if not hasattr(func, '__class__'):
97+
raise NotImplementedError("Use @lru_cache instead of memoize() for funcitons.")
98+
# For methods, we want the cache on the object, not on the class, in order
99+
# to not having to think about cache bloat and content becoming stale, so
100+
# we cannot set up the cache here.
101+
return decorate(func, _memoize)
102+

0 commit comments

Comments
 (0)