Cache prefetch
This commit is contained in:
parent
c2f6dba462
commit
2831a24b90
6 changed files with 70 additions and 34 deletions
|
@ -74,7 +74,17 @@ def cache_wrapper(prefix, timeout=None):
|
|||
if l0_cache:
|
||||
l0_cache.delete(cache_key)
|
||||
|
||||
def prefetch_multi(args_list):
|
||||
keys = []
|
||||
for args in args_list:
|
||||
keys.append(get_key(func, *args))
|
||||
results = cache.get_many(keys)
|
||||
for key, result in results.items():
|
||||
if result is not None:
|
||||
_set_l0(key, result)
|
||||
|
||||
wrapper.dirty = dirty
|
||||
wrapper.prefetch_multi = prefetch_multi
|
||||
|
||||
return wrapper
|
||||
|
||||
|
|
|
@ -253,24 +253,9 @@ class Profile(models.Model):
|
|||
max_length=300,
|
||||
)
|
||||
|
||||
@cache_wrapper(prefix="Pgbi2")
|
||||
def _get_basic_info(self):
|
||||
res = {
|
||||
"email": self.user.email,
|
||||
"username": self.user.username,
|
||||
"mute": self.mute,
|
||||
}
|
||||
if self.user.first_name:
|
||||
res["first_name"] = self.user.first_name
|
||||
if self.user.last_name:
|
||||
res["last_name"] = self.user.last_name
|
||||
if self.profile_image:
|
||||
res["profile_image_url"] = self.profile_image.url
|
||||
return res
|
||||
|
||||
@cached_property
|
||||
def _cached_info(self):
|
||||
return self._get_basic_info()
|
||||
return _get_basic_info(self.id)
|
||||
|
||||
@cached_property
|
||||
def organization(self):
|
||||
|
@ -412,6 +397,10 @@ class Profile(models.Model):
|
|||
or self.user.is_superuser
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def prefetch_profile_cache(self, profile_ids):
|
||||
_get_basic_info.prefetch_multi([(pid,) for pid in profile_ids])
|
||||
|
||||
class Meta:
|
||||
indexes = [
|
||||
models.Index(fields=["is_unlisted", "performance_points"]),
|
||||
|
@ -540,7 +529,7 @@ class OrganizationProfile(models.Model):
|
|||
def on_user_save(sender, instance, **kwargs):
|
||||
try:
|
||||
profile = instance.profile
|
||||
profile._get_basic_info.dirty(profile)
|
||||
_get_basic_info.dirty(profile.id)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
@ -551,4 +540,34 @@ def on_profile_save(sender, instance, **kwargs):
|
|||
return
|
||||
prev = sender.objects.get(id=instance.id)
|
||||
if prev.mute != instance.mute or prev.profile_image != instance.profile_image:
|
||||
instance._get_basic_info.dirty(instance)
|
||||
_get_basic_info.dirty(instance.id)
|
||||
|
||||
|
||||
@cache_wrapper(prefix="Pgbi2")
|
||||
def _get_basic_info(profile_id):
|
||||
profile = (
|
||||
Profile.objects.select_related("user")
|
||||
.only(
|
||||
"id",
|
||||
"mute",
|
||||
"profile_image",
|
||||
"user__username",
|
||||
"user__email",
|
||||
"user__first_name",
|
||||
"user__last_name",
|
||||
)
|
||||
.get(id=profile_id)
|
||||
)
|
||||
user = profile.user
|
||||
res = {
|
||||
"email": user.email,
|
||||
"username": user.username,
|
||||
"mute": profile.mute,
|
||||
"first_name": user.first_name or None,
|
||||
"last_name": user.last_name or None,
|
||||
"profile_image_url": profile.profile_image.url
|
||||
if profile.profile_image
|
||||
else None,
|
||||
}
|
||||
res = {k: v for k, v in res.items() if v is not None}
|
||||
return res
|
||||
|
|
|
@ -470,6 +470,7 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView):
|
|||
if context["in_hidden_subtasks_contest"]:
|
||||
for submission in context["submissions"]:
|
||||
self.modify_attrs(submission)
|
||||
|
||||
return context
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
|
|
|
@ -457,14 +457,13 @@ class UserList(QueryStringSortMixin, InfinitePaginationMixin, TitleMixin, ListVi
|
|||
queryset = (
|
||||
Profile.objects.filter(is_unlisted=False)
|
||||
.order_by(self.order, "id")
|
||||
.select_related("user")
|
||||
.only(
|
||||
"display_rank",
|
||||
"user__username",
|
||||
"points",
|
||||
"rating",
|
||||
"performance_points",
|
||||
"problem_count",
|
||||
"about",
|
||||
)
|
||||
)
|
||||
if self.request.organization:
|
||||
|
@ -472,11 +471,11 @@ class UserList(QueryStringSortMixin, InfinitePaginationMixin, TitleMixin, ListVi
|
|||
if (self.request.GET.get("friend") == "true") and self.request.profile:
|
||||
queryset = self.filter_friend_queryset(queryset)
|
||||
self.filter_friend = True
|
||||
|
||||
return queryset
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(UserList, self).get_context_data(**kwargs)
|
||||
Profile.prefetch_profile_cache([u.id for u in context["users"]])
|
||||
context["users"] = ranker(
|
||||
context["users"], rank=self.paginate_by * (context["page_obj"].number - 1)
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue