Fix/participant count consistency#29
Merged
Merged
Conversation
Five new endpoints for the remaining dashboard charts that fetch raw data:
- GET /v1/conferences/duration-summary
Returns conference counts bucketed by duration range (< 1m, 1-3m, etc.)
- GET /v1/conferences/participant-count-summary
Returns distribution of conferences by participant count
- GET /v1/issues/summary
Returns issue counts grouped by code with titles
- GET /v1/issues/gum-summary
Returns getusermedia_error issue counts grouped by error name
Also adds three new filter params to /v1/conferences for click-to-detail
modals on these charts:
- duration_gte, duration_lt (for duration chart)
- issue_code (for most-common-issues chart)
All endpoints accept appId, created_at_gte, created_at_lte and handle
both Python native ISO format and JavaScript's toISOString Z suffix.
Phases 2 and 3 of #20 — eliminates the need for the dashboard to
download all conferences (~38MB) and all issues (~73MB).
Adds three new aggregation endpoints that let the dashboard stop downloading full /connections and /sessions payloads to build charts client-side: - GET /v1/connections/summary — relay vs direct connection counts (replaces the Relayed-connections pie chart's client-side reduce) - GET /v1/connections/setup-time-summary — connection setup-time buckets with per-bucket conference_ids for click-to-detail - GET /v1/sessions/summary — browsers, OS, country, and city/geo aggregates (powers Browsers, OS, and Map charts in one roundtrip) Also accepts `conference_ids=a,b,c` on /conferences so the setup-time chart can page through matched conferences on click. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…se C of #20) With Phases 0-5 merged, every dashboard chart reads from a server-side aggregation endpoint. The SQL is fast with indexes, but the same ~8 queries run on every page load, and the heavy ones (sessions.summary, connections.setup_time_summary) still cost 400-800ms on a live tenant. Adds a thin caching layer in front of each summary view: - `app/summary_cache.py` — `cached_json(endpoint, request, compute)` hashes (endpoint + filter params) into a short key, reads Redis, falls through to `compute()` on miss, and writes back with a 60s TTL. Redis failures are tolerated (settings already has IGNORE_EXCEPTIONS). - Each of the eight summary views moves its existing compute body into a local `compute()` closure and returns through the helper. No change to the JSON shape, query logic, or error handling. - `manage.py prewarm_summaries` — scheduled command that iterates apps with recent traffic (default: any conference in the last 2 days) and runs every summary view with the 30d-window filters the dashboard sends by default. Intended to run every ~30s as an ECS scheduled task so first visitors never see a cold miss. Measured locally against a 7-day Production clone (~18k conferences / 38k sessions / 38k connections): endpoint cold warm conferences/summary 391ms → 12ms (33x) sessions/summary 748ms → 11ms (68x) connections/setup_time_summary 373ms → 11ms (34x) conferences/participant_count_summary 216ms → 7ms (31x) issues/gum_summary 107ms → 6ms (18x) connections/summary 57ms → 6ms (9.5x) issues/summary 45ms → 86ms (noise; both <100ms) conferences/duration_summary 19ms → 8ms (2.3x) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Unit-test cache key rules, hit/miss, TTL override, and soft-fail on get/set errors. - Smoke-test prewarm_summaries for zero apps and one recent app (8 views). Made-with: Cursor
The dashboard sends `new Date().toISOString()` minus 30 days as
created_at_gte (web app.vue:189), which is millisecond-precise. With the
unrounded value going straight into _make_key, every page load — even
back-to-back reloads — produced a unique SHA1 digest and a fresh cache
miss, so the warm path never served real users:
flush redis -> 0 keys
load dashboard -> 8 keys
reload -> 16 keys (8 stale + 8 fresh)
prewarm_summaries had the same problem on the write side: its own
since_window = utcnow() - 30d advanced every run, so the entries it
populated never matched what the dashboard requested.
Truncate ISO timestamps to the minute (YYYY-MM-DDTHH:MM) before hashing,
so two requests in the same wall-clock minute share an entry. Correctness
still holds because the 60s TTL bounds staleness regardless of bucket
size.
After the fix, two same-minute dashboard loads both produce 8 keys (no
growth), and the 2nd load's slow endpoints serve from cache:
before after
/v1/sessions/summary 2314ms -> 411ms
/v1/connections/setup-time-summary 1117ms -> 229ms
/v1/conferences/summary 994ms -> 48ms
Two regression tests added covering the bucket and the minute boundary.
Count only active non-SFU participants with a session on the conference, excluding peer stubs without sessions and SFU endpoints. Shared annotation in conference_query.py used by conferences list and participant-count summary. Co-authored-by: Cursor <cursoragent@cursor.com>
Contributor
Author
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f2c7aef4ce
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Use a correlated Subquery instead of Count on the outer participants join. Filtering by participantId narrowed that join to one person, so the aggregate incorrectly showed 1 for multi-participant calls. The subquery counts independently. Add regression test. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
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.
No description provided.