messages: Create function to calculate first visible message id.

This commit is contained in:
Vishnu Ks 2018-01-04 18:19:39 +05:30 committed by showell
parent f2a7d44c29
commit e6d3f8895f
3 changed files with 52 additions and 3 deletions

View File

@ -410,6 +410,11 @@ def flush_realm(sender: Any, **kwargs: Any) -> None:
users = realm.get_active_users()
delete_user_profile_caches(users)
# Deleting realm or updating message_visibility_limit
# attribute should clear the last_visible_message_id cache.
if kwargs.get('update_fields') is None or "message_visibility_limit" in kwargs['update_fields']:
cache_delete(realm_last_visible_message_id_cache_key(realm))
if realm.deactivated:
cache_delete(realm_user_dicts_cache_key(realm.id))
cache_delete(active_user_ids_cache_key(realm.id))
@ -420,6 +425,10 @@ def realm_alert_words_cache_key(realm):
# type: (Realm) -> Text
return u"realm_alert_words:%s" % (realm.string_id,)
def realm_last_visible_message_id_cache_key(realm):
# type: (Realm) -> Text
return u"realm_last_visible_message_id:%s" % (realm.string_id,)
# Called by models.py to flush the stream cache whenever we save a stream
# object.
def flush_stream(sender: Any, **kwargs: Any) -> None:

View File

@ -13,6 +13,7 @@ from zerver.lib.cache import (
generic_bulk_cached_fetch,
to_dict_cache_key,
to_dict_cache_key_id,
realm_last_visible_message_id_cache_key,
)
from zerver.lib.request import JsonableError
from zerver.lib.stream_subscription import (
@ -846,7 +847,18 @@ def apply_unread_message_event(user_profile: UserProfile,
if 'mentioned' in flags:
state['mentions'].add(message_id)
# This function will be used when we restrict search history for certain realms,
# but now it just allows all realms to see all messages.
# 4 hours is probably frequent enough to encourage upgrade
# and largely mitigates the cache-miss problem. We also
# don't need to restrict messages to exactly
# message_visibility_limit. The query is also reasonably fast
# so cache misses can be managed without cron job.
@cache_with_key(realm_last_visible_message_id_cache_key, timeout=3600*4)
def get_first_visible_message_id(realm: Realm) -> int:
return 0
if realm.message_visibility_limit is None:
return 0
try:
return Message.objects.filter(sender__realm=realm).values('id').\
order_by('-id')[realm.message_visibility_limit - 1]["id"]
except IndexError:
return 0

View File

@ -22,6 +22,8 @@ from zerver.lib.message import (
MessageDict,
messages_for_ids,
sew_messages_and_reactions,
get_first_visible_message_id,
realm_last_visible_message_id_cache_key,
)
from zerver.lib.test_helpers import (
@ -2731,3 +2733,29 @@ class MessageHydrationTest(ZulipTestCase):
self.assertIn('class="user-mention"', new_message['content'])
self.assertEqual(new_message['flags'], ['mentioned'])
class MessageVisibilityTest(ZulipTestCase):
def test_get_first_visible_message_id_with_no_limit(self) -> None:
realm = get_realm("zulip")
realm.message_visibility_limit = None
realm.save()
self.assertEqual(get_first_visible_message_id(realm), 0)
def test_get_first_visible_message_id_with_limit(self) -> None:
Message.objects.all().delete()
message_ids = [self.send_stream_message(self.example_email("othello"), "Scotland") for i in range(15)]
realm = get_realm("zulip")
realm.message_visibility_limit = 10
realm.save()
expected_message_id = message_ids[5]
self.assertEqual(get_first_visible_message_id(realm), expected_message_id)
# If the message_visibility_limit is greater than number of messages
# get_first_visible_message_id should return 0
message_visibility_limit = 50
realm.message_visibility_limit = message_visibility_limit
realm.save()
self.assertEqual(get_first_visible_message_id(realm), 0)