Supervisors and volunteers pages load every case contact in the org (13s requests, memory spikes)
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 58/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Ambito
- backend, performance
Direzione di ricerca
Start with app/policies/supervisor_policy.rb and app/models/user.rb, then trace how app/views/supervisors/index.html.erb uses volunteer counts. Run the policy and system specs named in the issue; use the suggested console data and compare query counts for both pages. Done means the pages avoid loading every contact and the N+1 queries, while the existing counts and specs remain unchanged.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Problem
/supervisors and /volunteers are the slowest pages in production. They also allocate the most memory, which likely contributes to the R14 memory errors in #7218.
From Scout APM, last 7 days:
| Endpoint | Avg response | Slowest trace | Allocations |
|---|---|---|---|
supervisors/index |
3.5 s | 13.4 s | ~800k |
volunteers/index |
1.2 s | 13.8 s | ~600k |
In both slow traces, one preload query takes 12–13 s and loads ~29,600 CaseContact rows. That's every case contact written by every volunteer in the org, loaded on every page view.
Root cause
app/policies/supervisor_policy.rb:
class Scope < ApplicationPolicy::Scope
def resolve
scope.includes(
:volunteers,
volunteers: [:supervisor, :case_assignments, :case_contacts]
)
end
end
The preload doesn't even help:
/volunteers(VolunteersController#index, line ~11) only uses@supervisorsfor the supervisor filter dropdown and its ids. It never touches contacts./supervisorscallsSupervisor#no_attempt_for_two_weeks(app/models/user.rb). That method callsvolunteer.case_contacts.none?andvolunteer.case_contacts.maximum(:created_at), which run fresh SQL anyway. The trace shows ~120 of each on top of the preload. It also runsSELECT * FROM case_assignments WHERE volunteer_id = ?161 times, an N+1.
Suggested fix
- Remove
:case_contacts(and probably all theincludes) fromSupervisorPolicy::Scope#resolve. A policy scope should filter, not eager-load. Add the includes the page needs at the call site instead. - Rewrite
no_attempt_for_two_weeksas one query per supervisor, or one grouped query for all supervisors. For example, count active volunteers with an active case assignment and nocase_contactscreated in the last 14 days. UseNOT EXISTSorMAX(created_at)grouped bycreator_id, not Ruby loops. - Fix the
case_assignmentsN+1 on/supervisors(volunteer.case_assignments.any?(&:active?)inside the loop). - Keep the existing
spec/policies/supervisor_policy_spec.rb,spec/system/supervisors/index_spec.rbandspec/system/volunteers/index_spec.rbpassing. The volunteer counts shown on/supervisorsmust not change. - Prosopite (N+1 detection) is already on in specs, so it will flag regressions.
How to verify locally
Seed data is small, so the slowness won't show up. Add a few thousand contacts in a console: FactoryBot.create_list(:case_contact, 3000, creator: Volunteer.first) in RAILS_ENV=development. Then compare the query count and time in the dev log before and after, for /supervisors and /volunteers as [email protected].
Difficulty: intermediate. It's mostly in two files (supervisor_policy.rb, user.rb), plus the views that read the counts (app/views/supervisors/index.html.erb).
- Lingua principale
- Ruby
- Stelle
- 382
- Fork
- 547
- Merge medio
- 2g 22h
- PR unite (30g)
- 46
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Include un Dockerfile o un file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di rubyforgood/casa
-
Remove leftover Cloud66 custom_web process from ProcfileForse già presa @ShahadatTest l’ha presa 1 giorno fa. ApertaDifficulty: Easy Good First Issue
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
rubyforgood/casa#7330 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
dependencies Difficulty: Easy Good First Issue
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 82/100
rubyforgood/casa#7325 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficulty: Easy Good First Issue Help Wanted javascript
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
rubyforgood/casa#7311 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficulty: Easy Good First Issue Help Wanted javascript
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
rubyforgood/casa#7310 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficulty: Easy Good First Issue Help Wanted javascript
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
rubyforgood/casa#7309 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di rubyforgood/casa
Issue simili
-
JWT::EncodedToken raises TypeError for a non-object headerForse già presa @anakinj l’ha presa oggi. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
jwt/ruby-jwt#780 · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
zold-io/zold-ruby-sdk#85 ·
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
I maintainer di solito rispondono entro 1 giorno