push notif: Send a batch of message IDs in one remove payload.

When a bunch of messages with active notifications are all read at
once -- e.g. by the user choosing to mark all messages, or all in a
stream, as read, or just scrolling quickly through a PM conversation
-- there can be a large batch of this information to convey.  Doing it
in a single GCM/FCM message is better for server congestion, and for
the device's battery.

The corresponding client-side logic is in zulip/zulip-mobile#3343 .

Existing clients today only understand one message ID at a time; so
accommodate them by sending individual GCM/FCM messages up to an
arbitrary threshold, with the rest only as a batch.

Also add an explicit test for this logic.  The existing tests
that happen to cause this function to run don't exercise the
last condition, so without a new test `--coverage` complains.
This commit is contained in:
Greg Price
2019-02-13 16:08:51 -08:00
committed by Tim Abbott
parent 28ff9670de
commit 9869153ae8
5 changed files with 102 additions and 30 deletions

View File

@@ -4016,16 +4016,29 @@ def do_mark_stream_messages_as_read(user_profile: UserProfile,
def do_clear_mobile_push_notifications_for_ids(user_profile: UserProfile,
message_ids: List[int]) -> None:
for user_message in UserMessage.objects.filter(
message_id__in=message_ids,
user_profile=user_profile).extra(
where=[UserMessage.where_active_push_notification()]):
event = {
"user_profile_id": user_profile.id,
"message_id": user_message.message_id,
filtered_message_ids = list(UserMessage.objects.filter(
message_id__in=message_ids,
user_profile=user_profile,
).extra(
where=[UserMessage.where_active_push_notification()],
).values_list('message_id', flat=True))
num_detached = settings.MAX_UNBATCHED_REMOVE_NOTIFICATIONS - 1
for message_id in filtered_message_ids[:num_detached]:
# Older clients (all clients older than 2019-02-13) will only
# see the first message ID in a given notification-message.
# To help them out, send a few of these separately.
queue_json_publish("missedmessage_mobile_notifications", {
"type": "remove",
}
queue_json_publish("missedmessage_mobile_notifications", event)
"user_profile_id": user_profile.id,
"message_ids": [message_id],
})
if filtered_message_ids[num_detached:]:
queue_json_publish("missedmessage_mobile_notifications", {
"type": "remove",
"user_profile_id": user_profile.id,
"message_ids": filtered_message_ids[num_detached:],
})
def do_update_message_flags(user_profile: UserProfile,
client: Client,