Repository navigation
Speed up and cache the iCal feeds - #431
Merged
Merged
Conversation
- Schedule page: cache the FullCalendar JSON string (Program#fullcalendar _events_json) instead of building it from cached records on every request. Drop the view fragment cache: its key included that JSON, so it never saved work, and it froze the "now" marker for the cache's life. - Breaks look up the venue's room guids once, not once per break. - Personal schedule: User#planned_event_ids gets the user's favourited, speaking and volunteering event ids in two queries, replacing Event#planned_for_user? (three queries per event). - All events: find unscheduled events with where.not instead of loading every confirmed event and subtracting arrays. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
icalendar_proposals ran several queries per event (Event#time, #room, #track, #difficulty_level). It now preloads what it reads and looks up the selected event schedule in memory. /calendar.ics also preloads each conference's venue, program and selected schedule. Both feeds are now cached in Rails.cache. /calendar.ics is keyed on the count and latest updated_at of conferences, programs and venues; schedule.ics on the program, selected schedule, conference and venue. Events, event schedules, schedules, tracks and rooms all touch their program, so edits to sessions invalidate the cache. Also: - Render the feed with render plain instead of render inline, so event text is no longer evaluated as an ERB template. Lines now end in CRLF as RFC 5545 requires. - Use append_categories for the difficulty and track categories. Pushing a plain String onto categories made to_ical raise, so any feed with a track or difficulty level returned a 500. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* origin/main: Render iCal feeds as plain text/calendar responses Paginate admin revision history and trim admin events preloads Load nav conference links with SQL instead of per-conference can? Share cached event cards between viewers who see the same card Find happening now sessions in SQL with HappeningNowQuery # Conflicts: # spec/controllers/schedules_controller_spec.rb
…ance * origin/main: Render iCal feeds as plain text/calendar responses Paginate admin revision history and trim admin events preloads Load nav conference links with SQL instead of per-conference can? Share cached event cards between viewers who see the same card Find happening now sessions in SQL with HappeningNowQuery # Conflicts: # app/controllers/conferences_controller.rb # app/controllers/schedules_controller.rb
Both rewrite SchedulesController#show. Keep #429's per-format structure and this branch's cached iCal output. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
/calendar.ics?full=1and/conferences/:id/schedule.icsare polled by calendar clients and were expensive on our 512 MB dyno.icalendar_proposalscalledEvent#time,#room,#trackand#difficulty_levelfor each event, so query count grew with the number of sessions./calendar.icsalso looked up each conference's program and venue separately.Fix
icalendar_proposalspreloads what it reads (event type, difficulty level, program, track with room and submitter, event schedules with room) and finds the selected event schedule in memory. The time and room logic is the same asEvent#timeandEvent#room./calendar.icspreloads venue, program and selected schedule for all conferences, and loads rooms with the event schedules (they're used for sorting). It no longer loads speakers and submitters, which the feed never used.Rails.cachefor up to 12 hours:/calendar.ics: key is the row count and latestupdated_atof conferences, programs and venues, plus full/short and the request host.schedule.ics: key is the program, selected schedule, conference and venue cache versions, plus the request host.Two existing bugs in the same lines, fixed here:
e.categories << "..."pushed a plain String thatto_icalcan't serialize. It now usesappend_categories.render inline:, which treats the string as an ERB template, so event text was evaluated. It now usesrender plain:withtext/calendar.Query counts
Measured in
spec/requests/ical_feeds_spec.rbwith the test null cache, so these are uncached renders. Counts include the auth and session queries./calendar.ics?full=1/conferences/:id/schedule.icsOn a cache hit,
/calendar.icsruns only the auth queries and threeCOUNT/MAXqueries.Output
I compared the before and after output on the same seeded data: short feed, full feed with a self-organized track, nil room, nil event type and unscheduled events, and two
schedule.icsfeeds. The only difference is line endings. They are now CRLF, as RFC 5545 requires. Before, they were LF because the ERB rendering converted them. For "before", I applied theappend_categoriesfix, since the original code returned a 500.Trade-offs
DTSTAMPnow records when the feed was cached, not when it was requested. That is allowed by the spec, and clients use UID and LAST-MODIFIED.update_columnand the like). No app code does that for these models today. Entries expire after 12 hours regardless.Rails.cachestore production uses. If that is an in-process memory store, a few hundred KB of iCal text sits in RAM./calendar.icsis admin-only today:Abilitynever grants:calendarto guests or regular users, so anonymous requests redirect to/. I left that alone. The new spec signs in as admin.🤖 Generated with Claude Code