actions: Send reaction events to subscribers with history access.

Previously, if a user subscribed to a stream with
history_public_to_subscribers, and then was looking at old messages in
the stream, they would not get live-updates for that stream, because
of the structure in how notify_reaction_update only looked at
UserMessage rows (we had a previous workaround involving the
`historical` field in `UserMessage` which had already made it work if
the user themselves added the reaction).

We fix this by including all subscribers with history access in the
set of recipients for update events.

Fixes a bug that was confused with #16942.
This commit is contained in:
LoopThrough-i-j
2021-03-27 07:35:56 +05:30
committed by Tim Abbott
parent 277fbb3f02
commit ffd0d822fe
2 changed files with 157 additions and 10 deletions

View File

@@ -133,6 +133,7 @@ from zerver.lib.stream_subscription import (
get_stream_subscriptions_for_users,
get_subscribed_stream_ids_for_user,
num_subscribers_for_stream_id,
subscriber_ids_with_stream_history_access,
)
from zerver.lib.stream_topic import StreamTopicTarget
from zerver.lib.streams import (
@@ -2159,18 +2160,28 @@ def notify_reaction_update(
update_to_dict_cache([message])
# Recipients for message update events, including reactions, are
# everyone who got the original message. This means reactions
# won't live-update in preview narrows, but it's the right
# performance tradeoff, since otherwise we'd need to send all
# reactions to public stream messages to every browser for every
# client in the organization, which doesn't scale.
# everyone who got the original message, plus subscribers of
# streams with the access to stream's full history.
#
# However, to ensure that reactions do live-update for any user
# who has actually participated in reacting to a message, we add a
# This means reactions won't live-update in preview narrows for a
# stream the user isn't yet subscribed to; this is the right
# performance tradeoff to avoid sending every reaction to public
# stream messages to all users.
#
# To ensure that reactions do live-update for any user who has
# actually participated in reacting to a message, we add a
# "historical" UserMessage row for any user who reacts to message,
# subscribing them to future notifications.
ums = UserMessage.objects.filter(message=message.id)
send_event(user_profile.realm, event, [um.user_profile_id for um in ums])
# subscribing them to future notifications, even if they are not
# subscribed to the stream.
user_ids = set(
UserMessage.objects.filter(message=message.id).values_list("user_profile_id", flat=True)
)
if message.recipient.type == Recipient.STREAM:
stream_id = message.recipient.type_id
stream = Stream.objects.get(id=stream_id)
user_ids |= subscriber_ids_with_stream_history_access(stream)
send_event(user_profile.realm, event, list(user_ids))
def do_add_reaction(