Merged in [17035] from housley@vigilsec.com:

Improve performance for some agenda-related pages
 - Legacy-Id: 17063
Note: SVN reference [17035] has been migrated to Git commit ff653634c8
This commit is contained in:
Henrik Levkowetz 2019-11-20 07:00:46 +00:00
commit b6a82218f6
2 changed files with 42 additions and 22 deletions

View file

@ -11,7 +11,7 @@ import re
from tempfile import mkstemp
from django.http import HttpRequest, Http404
from django.db.models import Max, Q, Prefetch, F
from django.db.models import Max, Q
from django.conf import settings
from django.core.cache import cache
from django.urls import reverse
@ -164,41 +164,52 @@ def get_schedule_by_name(meeting, owner, name):
return meeting.schedule_set.filter(name = name).first()
def preprocess_assignments_for_agenda(assignments_queryset, meeting):
# prefetch some stuff to prevent a myriad of small, inefficient queries
# prefetch was not improving performance, except for json_agenda, so
# it was removed. Saved in comment in case others find it useful
# in the future ...
#
#.prefetch_related(
# Prefetch("session__materials",
# queryset=Document.objects.exclude(states__type=F("type"),states__slug='deleted').select_related("group").order_by("sessionpresentation__order"),
# to_attr="prefetched_active_materials",
# ),
# "timeslot__meeting",
# )
assignments_queryset = assignments_queryset.select_related(
"timeslot", "timeslot__location", "timeslot__type",
"session",
"session__group", "session__group__charter", "session__group__charter__group",
).prefetch_related(
Prefetch("session__materials",
queryset=Document.objects.exclude(states__type=F("type"),states__slug='deleted').select_related("group").order_by("sessionpresentation__order"),
to_attr="prefetched_active_materials",
),
"timeslot__meeting",
)
"session", "session__group", "session__group__charter",
"session__group__charter__group",
)
assignments = list(assignments_queryset) # make sure we're set in stone
# removed list(); it was consuming a very large amount of processor time
# assignments = list(assignments_queryset) # make sure we're set in stone
assignments = assignments_queryset
meeting_time = datetime.datetime.combine(meeting.date, datetime.time())
# replace groups with historic counterparts
groups = [ ]
for a in assignments:
if a.session:
a.session.historic_group = None
groups = [a.session.group for a in assignments if a.session and a.session.group]
if a.session.group and a.session.group not in groups:
groups.append(a.session.group)
group_replacements = find_history_replacements_active_at(groups, meeting_time)
parent_id_set = set()
for a in assignments:
if a.session and a.session.group:
a.session.historic_group = group_replacements.get(a.session.group_id)
# replace group parents with historic counterparts
for a in assignments:
if a.session and a.session.historic_group:
a.session.historic_group.historic_parent = None
if a.session.historic_group:
a.session.historic_group.historic_parent = None
if a.session.historic_group.parent_id:
parent_id_set.add(a.session.historic_group.parent_id)
parents = Group.objects.filter(pk__in=set(a.session.historic_group.parent_id for a in assignments if a.session and a.session.historic_group and a.session.historic_group.parent_id))
parents = Group.objects.filter(pk__in=parent_id_set)
parent_replacements = find_history_replacements_active_at(parents, meeting_time)
for a in assignments:

View file

@ -34,7 +34,7 @@ from django.contrib.auth.decorators import login_required
from django.core.exceptions import ValidationError
from django.core.validators import URLValidator
from django.urls import reverse,reverse_lazy
from django.db.models import Min, Max, Q
from django.db.models import F, Min, Max, Prefetch, Q
from django.forms.models import modelform_factory, inlineformset_factory
from django.template import TemplateDoesNotExist
from django.template.loader import render_to_string
@ -949,6 +949,15 @@ def json_agenda(request, num=None ):
assignments = meeting.agenda.assignments.exclude(session__type__in=['lead','offagenda','break','reg'])
# Update the assignments with historic information, i.e., valid at the
# time of the meeting
assignments = assignments.prefetch_related(
Prefetch("session__materials",
queryset=Document.objects.exclude(states__type=F("type"),states__slug='deleted').select_related("group").order_by("sessionpresentation__order"),
to_attr="prefetched_active_materials",
),
"session__materials__docevent_set",
"session__sessionpresentation_set",
"timeslot__meeting",
)
assignments = preprocess_assignments_for_agenda(assignments, meeting)
for asgn in assignments:
sessdict = dict()
@ -964,9 +973,9 @@ def json_agenda(request, num=None ):
}
if asgn.session.historic_group.is_bof():
sessdict['is_bof'] = True
if asgn.session.historic_group.type_id in ['wg','rg', 'ag',] or asgn.session.historic_group.acronym in ['iesg',]:
sessdict['group']['parent'] = asgn.session.historic_group.historic_parent.acronym
parent_acronyms.add(asgn.session.historic_group.historic_parent.acronym)
if asgn.session.historic_group.type_id in ['wg','rg', 'ag',] or asgn.session.historic_group.acronym in ['iesg',]:
sessdict['group']['parent'] = asgn.session.historic_group.historic_parent.acronym
parent_acronyms.add(asgn.session.historic_group.historic_parent.acronym)
if asgn.session.name:
sessdict['name'] = asgn.session.name
else: