From d22f1a170557b11514e9f98735cd25a53a3588ef Mon Sep 17 00:00:00 2001 From: Kevin Chung Date: Tue, 30 Jun 2020 18:36:56 -0400 Subject: [PATCH] Properly cache User.place and User.score constants (#1525) * Cache accesses of `User.place` and `User.score` in the user attrs wrapper via Jinja --- CTFd/cache/__init__.py | 17 +++++++++++++++++ CTFd/constants/teams.py | 14 ++++---------- CTFd/constants/users.py | 14 ++++---------- CTFd/utils/user/__init__.py | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/CTFd/cache/__init__.py b/CTFd/cache/__init__.py index a06d003f..a7f92d97 100644 --- a/CTFd/cache/__init__.py +++ b/CTFd/cache/__init__.py @@ -30,14 +30,31 @@ def clear_standings(): from CTFd.utils.scores import get_standings, get_team_standings, get_user_standings from CTFd.api.v1.scoreboard import ScoreboardDetail, ScoreboardList from CTFd.api import api + from CTFd.utils.user import ( + get_user_score, + get_user_place, + get_team_score, + get_team_place, + ) + # Clear out the bulk standings functions cache.delete_memoized(get_standings) cache.delete_memoized(get_team_standings) cache.delete_memoized(get_user_standings) + + # Clear out the individual helpers for accessing score via the model cache.delete_memoized(Users.get_score) cache.delete_memoized(Users.get_place) cache.delete_memoized(Teams.get_score) cache.delete_memoized(Teams.get_place) + + # Clear the Jinja Attrs constants + cache.delete_memoized(get_user_score) + cache.delete_memoized(get_user_place) + cache.delete_memoized(get_team_score) + cache.delete_memoized(get_team_place) + + # Clear out HTTP request responses cache.delete(make_cache_key(path="scoreboard.listing")) cache.delete(make_cache_key(path=api.name + "." + ScoreboardList.endpoint)) cache.delete(make_cache_key(path=api.name + "." + ScoreboardDetail.endpoint)) diff --git a/CTFd/constants/teams.py b/CTFd/constants/teams.py index 09408c0d..16893a9e 100644 --- a/CTFd/constants/teams.py +++ b/CTFd/constants/teams.py @@ -29,21 +29,15 @@ class _TeamAttrsWrapper: @property def place(self): - from CTFd.utils.user import get_current_team + from CTFd.utils.user import get_team_place - team = get_current_team() - if team: - return team.place - return None + return get_team_place(team_id=self.id) @property def score(self): - from CTFd.utils.user import get_current_team + from CTFd.utils.user import get_team_score - team = get_current_team() - if team: - return team.score - return None + return get_team_score(team_id=self.id) Team = _TeamAttrsWrapper() diff --git a/CTFd/constants/users.py b/CTFd/constants/users.py index 78c528fc..4bdc8d0d 100644 --- a/CTFd/constants/users.py +++ b/CTFd/constants/users.py @@ -31,21 +31,15 @@ class _UserAttrsWrapper: @property def place(self): - from CTFd.utils.user import get_current_user + from CTFd.utils.user import get_user_place - user = get_current_user() - if user: - return user.place - return None + return get_user_place(user_id=self.id) @property def score(self): - from CTFd.utils.user import get_current_user + from CTFd.utils.user import get_user_score - user = get_current_user() - if user: - return user.score - return None + return get_user_score(user_id=self.id) User = _UserAttrsWrapper() diff --git a/CTFd/utils/user/__init__.py b/CTFd/utils/user/__init__.py index 7d68c40e..cbcfa1ee 100644 --- a/CTFd/utils/user/__init__.py +++ b/CTFd/utils/user/__init__.py @@ -52,6 +52,38 @@ def get_user_attrs(user_id): return None +@cache.memoize(timeout=300) +def get_user_place(user_id): + user = Users.query.filter_by(id=user_id).first() + if user: + return user.account.place + return None + + +@cache.memoize(timeout=300) +def get_user_score(user_id): + user = Users.query.filter_by(id=user_id).first() + if user: + return user.account.score + return None + + +@cache.memoize(timeout=300) +def get_team_place(team_id): + team = Teams.query.filter_by(id=team_id).first() + if team: + return team.place + return None + + +@cache.memoize(timeout=300) +def get_team_score(team_id): + team = Teams.query.filter_by(id=team_id).first() + if team: + return team.score + return None + + def get_current_team(): if authed(): user = get_current_user()