Make chat faster
This commit is contained in:
parent
58f3807b8d
commit
e5b2481345
10 changed files with 135 additions and 102 deletions
33
chat_box/migrations/0015_room_last_msg_time.py
Normal file
33
chat_box/migrations/0015_room_last_msg_time.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Generated by Django 3.2.18 on 2023-11-02 01:41
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
def migrate(apps, schema_editor):
|
||||
Room = apps.get_model("chat_box", "Room")
|
||||
Message = apps.get_model("chat_box", "Message")
|
||||
|
||||
for room in Room.objects.all():
|
||||
messages = room.message_set
|
||||
last_msg = messages.first()
|
||||
if last_msg:
|
||||
room.last_msg_time = last_msg.time
|
||||
room.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("chat_box", "0014_userroom_unread_count"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="room",
|
||||
name="last_msg_time",
|
||||
field=models.DateTimeField(
|
||||
db_index=True, null=True, verbose_name="last seen"
|
||||
),
|
||||
),
|
||||
migrations.RunPython(migrate, migrations.RunPython.noop, atomic=True),
|
||||
]
|
|
@ -1,6 +1,7 @@
|
|||
from django.db import models
|
||||
from django.db.models import CASCADE, Q
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.functional import cached_property
|
||||
|
||||
|
||||
from judge.models.profile import Profile
|
||||
|
@ -17,25 +18,39 @@ class Room(models.Model):
|
|||
user_two = models.ForeignKey(
|
||||
Profile, related_name="user_two", verbose_name="user 2", on_delete=CASCADE
|
||||
)
|
||||
last_msg_time = models.DateTimeField(
|
||||
verbose_name=_("last seen"), null=True, db_index=True
|
||||
)
|
||||
|
||||
class Meta:
|
||||
app_label = "chat_box"
|
||||
|
||||
@cache_wrapper(prefix="Rc")
|
||||
def contain(self, profile):
|
||||
return self.user_one == profile or self.user_two == profile
|
||||
@cache_wrapper(prefix="Rinfo")
|
||||
def _info(self):
|
||||
return {
|
||||
"user_ids": [self.user_one.id, self.user_two.id],
|
||||
"last_message": self.message_set.first().body,
|
||||
}
|
||||
|
||||
@cached_property
|
||||
def _cached_info(self):
|
||||
return self._info()
|
||||
|
||||
def contain(self, profile):
|
||||
return profile.id in self._cached_info["user_ids"]
|
||||
|
||||
@cache_wrapper(prefix="Rou")
|
||||
def other_user(self, profile):
|
||||
return self.user_one if profile == self.user_two else self.user_two
|
||||
|
||||
@cache_wrapper(prefix="Rus")
|
||||
def other_user_id(self, profile):
|
||||
user_ids = self._cached_info["user_ids"]
|
||||
return sum(user_ids) - profile.id
|
||||
|
||||
def users(self):
|
||||
return [self.user_one, self.user_two]
|
||||
|
||||
@cache_wrapper(prefix="Rlmb")
|
||||
def last_message_body(self):
|
||||
return self.message_set.first().body
|
||||
return self._cached_info["last_message"]
|
||||
|
||||
|
||||
class Message(models.Model):
|
||||
|
|
|
@ -84,8 +84,8 @@ class ChatView(ListView):
|
|||
self.room_id = request_room
|
||||
self.messages = (
|
||||
Message.objects.filter(hidden=False, room=self.room_id, id__lt=last_id)
|
||||
.select_related("author", "author__user")
|
||||
.defer("author__about", "author__user_script")[:page_size]
|
||||
.select_related("author")
|
||||
.only("body", "time", "author__rating", "author__display_rank")[:page_size]
|
||||
)
|
||||
if not only_messages:
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
@ -204,7 +204,9 @@ def post_message(request):
|
|||
},
|
||||
)
|
||||
else:
|
||||
Room.last_message_body.dirty(room)
|
||||
Room._info.dirty(room)
|
||||
room.last_msg_time = new_message.time
|
||||
room.save()
|
||||
|
||||
for user in room.users():
|
||||
event.post(
|
||||
|
@ -351,11 +353,11 @@ def get_online_status(profile, other_profile_ids, rooms=None):
|
|||
room = Room.objects.get(id=i["room"])
|
||||
other_profile = room.other_user(profile)
|
||||
count[other_profile.id] = i["unread_count"]
|
||||
rooms = Room.objects.filter(id__in=rooms)
|
||||
for room in rooms:
|
||||
room = Room.objects.get(id=room)
|
||||
other_profile = room.other_user(profile)
|
||||
last_msg[other_profile.id] = room.last_message_body()
|
||||
room_of_user[other_profile.id] = room.id
|
||||
other_profile_id = room.other_user_id(profile)
|
||||
last_msg[other_profile_id] = room.last_message_body()
|
||||
room_of_user[other_profile_id] = room.id
|
||||
|
||||
for other_profile in other_profiles:
|
||||
is_online = False
|
||||
|
@ -389,9 +391,6 @@ def get_status_context(profile, include_ignored=False):
|
|||
recent_profile = (
|
||||
Room.objects.filter(Q(user_one=profile) | Q(user_two=profile))
|
||||
.annotate(
|
||||
last_msg_time=Subquery(
|
||||
Message.objects.filter(room=OuterRef("pk")).values("time")[:1]
|
||||
),
|
||||
other_user=Case(
|
||||
When(user_one=profile, then="user_two"),
|
||||
default="user_one",
|
||||
|
@ -412,28 +411,15 @@ def get_status_context(profile, include_ignored=False):
|
|||
.values_list("id", flat=True)
|
||||
)
|
||||
|
||||
all_user_status = (
|
||||
queryset.filter(last_access__gte=last_5_minutes)
|
||||
.annotate(is_online=Case(default=True, output_field=BooleanField()))
|
||||
.order_by("-rating")
|
||||
.exclude(id__in=admin_list)
|
||||
.exclude(id__in=recent_profile_ids)
|
||||
.values_list("id", flat=True)[:30]
|
||||
)
|
||||
|
||||
return [
|
||||
{
|
||||
"title": "Recent",
|
||||
"title": _("Recent"),
|
||||
"user_list": get_online_status(profile, recent_profile_ids, recent_rooms),
|
||||
},
|
||||
{
|
||||
"title": "Admin",
|
||||
"title": _("Admin"),
|
||||
"user_list": get_online_status(profile, admin_list),
|
||||
},
|
||||
{
|
||||
"title": "Other",
|
||||
"user_list": get_online_status(profile, all_user_status),
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue