Exclude dormant users from buddy list queries.

If a user has not shown activity in two weeks, we exclude
them from the buddy list.  This should help performance for
large realms and mobile clients.
This commit is contained in:
Steve Howell
2017-02-19 07:43:32 -08:00
committed by Tim Abbott
parent 2420df8415
commit 3a332aee0b
2 changed files with 46 additions and 1 deletions

View File

@@ -1430,6 +1430,12 @@ class UserPresence(models.Model):
return UserPresence.get_status_dicts_for_query(query, mobile_user_ids)
@staticmethod
def exclude_old_users(query):
# type: (QuerySet) -> QuerySet
two_weeks_ago = timezone.now() - datetime.timedelta(weeks=2)
return query.filter(timestamp__gte=two_weeks_ago)
@staticmethod
def get_status_dict_by_realm(realm_id):
# type: (int) -> DefaultDict[Any, Dict[Any, Any]]
@@ -1437,7 +1443,11 @@ class UserPresence(models.Model):
user_profile__realm_id=realm_id,
user_profile__is_active=True,
user_profile__is_bot=False
).values(
)
query = UserPresence.exclude_old_users(query)
query = query.values(
'client__name',
'status',
'timestamp',

View File

@@ -22,6 +22,7 @@ from zerver.models import (
Client,
UserActivity,
UserProfile,
UserPresence,
)
import datetime
@@ -57,6 +58,40 @@ class TestClientModel(ZulipTestCase):
client = make_client('some_client')
self.assertEqual(str(client), u'<Client: some_client>')
class UserPresenceModelTests(ZulipTestCase):
def test_date_logic(self):
# type: () -> None
UserPresence.objects.all().delete()
email = "hamlet@zulip.com"
user_profile = get_user_profile_by_email(email)
presence_dct = UserPresence.get_status_dict_by_realm(user_profile.realm_id)
self.assertEqual(len(presence_dct), 0)
self.login(email)
result = self.client_post("/json/users/me/presence", {'status': 'active'})
self.assert_json_success(result)
presence_dct = UserPresence.get_status_dict_by_realm(user_profile.realm_id)
self.assertEqual(len(presence_dct), 1)
self.assertEqual(presence_dct[email]['website']['status'], 'active')
def back_date(num_weeks):
# type: (int) -> None
user_presence = UserPresence.objects.filter(user_profile=user_profile)[0]
user_presence.timestamp = timezone.now() - datetime.timedelta(weeks=num_weeks)
user_presence.save()
# Simulate the presence being a week old first. Nothing should change.
back_date(num_weeks=1)
presence_dct = UserPresence.get_status_dict_by_realm(user_profile.realm_id)
self.assertEqual(len(presence_dct), 1)
# If the UserPresence row is three weeks old, we ignore it.
back_date(num_weeks=3)
presence_dct = UserPresence.get_status_dict_by_realm(user_profile.realm_id)
self.assertEqual(len(presence_dct), 0)
class UserPresenceTests(ZulipTestCase):
def test_invalid_presence(self):
# type: () -> None