bug: match page re-checks every permission every second - #588
Merged
Merged
Conversation
The match subscription asked for thirteen permission and membership fields plus the organizer's full profile on every tick. Each is a function call the database re-runs per row, and none of them move without a status change or an organizer action. Splits them into a query and refetches it on those events. can_start and can_check_in stay live -- they read lineup readiness.
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.
The match subscription asked for thirteen permission and membership fields plus the organizer's full profile on every tick. Each of those is a function call the database re-runs for the row, and none of them move without a status change or an organizer action.
Measured warm against prod, one match row costs 9.56 ms across just the 19 permission functions I timed, and the worst offenders are the organizer checks this moves out:
is_match_organizermatch_requested_organizeris_captainis_coachis_match_organizeris the notable one — the subscription requested it directly andcan_cancel,can_check_inandcan_assign_servereach call it internally, so the same three-table join ran several times per row per tick with identical inputs.Moved to a
matchStaticquery, merged back into a singlematchcomputed so no child component changes: the membership and permission booleans,min/max_players_per_lineup,map_veto_type,organizer(which was pulling elo and three sanction checks), andtournament_brackets.Refetched on status change, on server assignment, and explicitly after
callForOrganizerand a match options save.can_startandcan_check_indeliberately stay in the subscription since they read lineup readiness.can_startis the single most expensive function at 2.98 ms but only in the pre-match states — once a match is Live or over it returns on its first status check.Verified every moved field is still consumed somewhere, and the full suite passes (111 tests). The two prettier warnings on these files are pre-existing on main and left alone.
Follow-ups this does not touch: the lineup player profiles (about 13 players × elo + sanctions per tick) and the per-round kill/assist payload, which together are the larger share of this query's 16,750 buffers per call.