Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions ietf/meeting/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,25 +250,39 @@ def get_attendance(self):
# MeetingRegistration.attended started conflating badge-pickup and session attendance before IETF 114.
# We've separated session attendance off to ietf.meeting.Attended, but need to report attendance at older
# meetings correctly.

#
# Looking up by registration and attendance records separately and joining in
# python is far faster than combining the Q objects in the query (~100x).
# Further optimization may be possible, but the queries are tricky...
attended_per_meeting_registration = (
Q(registration__meeting=self) & (
Q(registration__attended=True) |
Q(registration__checkedin=True)
)
)
attendees_by_reg = set(
Person.objects.filter(attended_per_meeting_registration).values_list(
"pk", flat=True
)
)

attended_per_meeting_attended = (
Q(attended__session__meeting=self)
# Note that we are not filtering to plenary, wg, or rg sessions
# as we do for nomcom eligibility - if picking up a badge (see above)
# is good enough, just attending e.g. a training session is also good enough
)
attended = Person.objects.filter(
attended_per_meeting_registration | attended_per_meeting_attended
).distinct()

onsite = set(attended.filter(registration__meeting=self, registration__tickets__attendance_type__slug='onsite'))
remote = set(attended.filter(registration__meeting=self, registration__tickets__attendance_type__slug='remote'))
attendees_by_att = set(
Person.objects.filter(attended_per_meeting_attended).values_list(
"pk", flat=True
)
)

attendees = Person.objects.filter(
pk__in=attendees_by_att | attendees_by_reg
)
onsite = set(attendees.filter(registration__meeting=self, registration__tickets__attendance_type__slug='onsite'))
remote = set(attendees.filter(registration__meeting=self, registration__tickets__attendance_type__slug='remote'))
remote.difference_update(onsite)

return Attendance(
Expand Down
39 changes: 35 additions & 4 deletions ietf/meeting/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1027,10 +1027,41 @@ def generate_proceedings_content(meeting, force_refresh=False):
:force_refresh: true to force regeneration and cache refresh
"""
cache = caches["default"]
cache_version = Document.objects.filter(session__meeting__number=meeting.number).aggregate(Max('time'))["time__max"]
# Include proceedings_final in the bare_key so we'll always reflect that accurately, even at the cost of
# a recomputation in the view
bare_key = f"proceedings.{meeting.number}.{cache_version}.final={meeting.proceedings_final}"
key_components = [
"proceedings",
str(meeting.number),
]
if meeting.proceedings_final:
# Freeze the cache key once proceedings are finalized. Further changes will
# not be picked up until the cache expires or is refreshed by the
# proceedings_content_refresh_task()
key_components.append("final")
else:
# Build a cache key that changes when materials are modified. For all but drafts,
# use the last modification time of the document. Exclude drafts from this because
# revisions long after the meeting ends will otherwise show up as changes and
# incorrectly invalidate the cache. Instead, include an ordered list of the
# drafts linked to the meeting so adding or removing drafts will trigger a
# recalculation. The list is long but that doesn't matter because we hash it into
# a fixed-length key.
meeting_docs = Document.objects.filter(session__meeting__number=meeting.number)
last_materials_update = (
meeting_docs.exclude(type_id="draft")
.filter(session__meeting__number=meeting.number)
.aggregate(Max("time"))["time__max"]
)
draft_names = (
meeting_docs
.filter(type_id="draft")
.order_by("name")
.values_list("name", flat=True)
)
key_components += [
last_materials_update.isoformat() if last_materials_update else "-",
",".join(draft_names),
]

bare_key = ".".join(key_components)
cache_key = sha384(bare_key.encode("utf8")).hexdigest()
if not force_refresh:
cached_content = cache.get(cache_key, None)
Expand Down
Loading