From b666f554f481eb98250cda2b8c9a2115b40ba158 Mon Sep 17 00:00:00 2001 From: levlam Date: Wed, 21 Nov 2018 15:23:43 +0300 Subject: [PATCH] Fix flush_pending_new_message_notifications. GitOrigin-RevId: b3b2e75d95760c2f57e71a4eb66da0674ea56da0 --- td/telegram/MessagesManager.cpp | 64 ++++++++++++++++++----------- td/telegram/MessagesManager.h | 4 +- td/telegram/NotificationManager.cpp | 38 +++++++++-------- td/telegram/NotificationManager.h | 6 +-- 4 files changed, 66 insertions(+), 46 deletions(-) diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 8bb854d2d..0ce50dc98 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -17466,31 +17466,35 @@ void MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f } if (!force && (!have_settings || !d->pending_new_message_notifications.empty())) { - LOG(INFO) << "Delay new message notification for " << m->message_id << " in " << d->dialog_id << " with " - << d->pending_new_message_notifications.size() << " already waiting messages"; + VLOG(notifications) << "Delay new message notification for " << m->message_id << " in " << d->dialog_id << " with " + << d->pending_new_message_notifications.size() << " already waiting messages"; if (d->pending_new_message_notifications.empty()) { create_actor( "FlushPendingNewMessageNotificationsSleepActor", 5.0, PromiseCreator::lambda([actor_id = actor_id(this), dialog_id = d->dialog_id](Result result) { - VLOG(notifications) << "Flush pending notifications in " << dialog_id << " by timeout"; - send_closure(actor_id, &MessagesManager::flush_pending_new_message_notifications, dialog_id); + send_closure(actor_id, &MessagesManager::flush_pending_new_message_notifications, dialog_id, DialogId()); })) .release(); } - d->pending_new_message_notifications.push_back(m->message_id); - auto promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_id = d->dialog_id](Result result) { - VLOG(notifications) << "Flush pending notifications in " << dialog_id - << " because of received notification settings"; - send_closure(actor_id, &MessagesManager::flush_pending_new_message_notifications, dialog_id); - }); - if (settings_dialog == nullptr && have_input_peer(settings_dialog_id, AccessRights::Read)) { - force_create_dialog(settings_dialog_id, "add_new_message_notification"); - settings_dialog = get_dialog(settings_dialog_id); - } - if (settings_dialog != nullptr) { - send_get_dialog_notification_settings_query(settings_dialog_id, std::move(promise)); - } else { - send_get_dialog_query(settings_dialog_id, std::move(promise)); + auto last_settings_dialog_id = + (d->pending_new_message_notifications.empty() ? DialogId() : d->pending_new_message_notifications.back().first); + d->pending_new_message_notifications.emplace_back((have_settings ? DialogId() : settings_dialog_id), m->message_id); + if (!have_settings && last_settings_dialog_id != settings_dialog_id) { + VLOG(notifications) << "Fetch notification settings for " << settings_dialog_id; + auto promise = PromiseCreator::lambda( + [actor_id = actor_id(this), dialog_id = d->dialog_id, settings_dialog_id](Result result) { + send_closure(actor_id, &MessagesManager::flush_pending_new_message_notifications, dialog_id, + settings_dialog_id); + }); + if (settings_dialog == nullptr && have_input_peer(settings_dialog_id, AccessRights::Read)) { + force_create_dialog(settings_dialog_id, "add_new_message_notification"); + settings_dialog = get_dialog(settings_dialog_id); + } + if (settings_dialog != nullptr) { + send_get_dialog_notification_settings_query(settings_dialog_id, std::move(promise)); + } else { + send_get_dialog_query(settings_dialog_id, std::move(promise)); + } } return; } @@ -17506,19 +17510,33 @@ void MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f m->disable_notification, m->notification_id, create_new_message_notification(m->message_id)); } -void MessagesManager::flush_pending_new_message_notifications(DialogId dialog_id) { +void MessagesManager::flush_pending_new_message_notifications(DialogId dialog_id, DialogId settings_dialog_id) { auto d = get_dialog(dialog_id); CHECK(d != nullptr); if (d->pending_new_message_notifications.empty()) { return; } - auto message_ids = std::move(d->pending_new_message_notifications); - reset_to_empty(d->pending_new_message_notifications); - for (auto message_id : message_ids) { - auto m = get_message(d, message_id); + for (auto &it : d->pending_new_message_notifications) { + if (it.first == settings_dialog_id || !settings_dialog_id.is_valid()) { + it.first = DialogId(); + } + } + + VLOG(notifications) << "Flush pending notifications in " << dialog_id + << " because of received notification settings in " << settings_dialog_id; + auto it = d->pending_new_message_notifications.begin(); + while (it != d->pending_new_message_notifications.end() && it->first == DialogId()) { + auto m = get_message(d, it->second); if (m != nullptr) { add_new_message_notification(d, m, true); } + ++it; + } + + if (it == d->pending_new_message_notifications.end()) { + reset_to_empty(d->pending_new_message_notifications); + } else { + d->pending_new_message_notifications.erase(d->pending_new_message_notifications.begin(), it); } } diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index e6e34c0bf..ed274ee71 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -905,7 +905,7 @@ class MessagesManager : public Actor { std::unordered_set deleted_message_ids; - std::vector pending_new_message_notifications; + std::vector> pending_new_message_notifications; string client_data; @@ -1459,7 +1459,7 @@ class MessagesManager : public Actor { void add_new_message_notification(Dialog *d, Message *m, bool force); - void flush_pending_new_message_notifications(DialogId dialog_id); + void flush_pending_new_message_notifications(DialogId dialog_id, DialogId settings_dialog_id); void remove_dialog_message_notifications(const Dialog *d) const; diff --git a/td/telegram/NotificationManager.cpp b/td/telegram/NotificationManager.cpp index ecae69920..77e530cf3 100644 --- a/td/telegram/NotificationManager.cpp +++ b/td/telegram/NotificationManager.cpp @@ -33,7 +33,9 @@ void NotificationManager::on_flush_pending_notifications_timeout_callback(void * } auto notification_manager = static_cast(notification_manager_ptr); - notification_manager->flush_pending_notifications(NotificationGroupId(narrow_cast(group_id_int))); + send_closure_later(notification_manager->actor_id(notification_manager), + &NotificationManager::flush_pending_notifications, + NotificationGroupId(narrow_cast(group_id_int))); } bool NotificationManager::is_disabled() const { @@ -221,8 +223,8 @@ void NotificationManager::send_update_notification(NotificationGroupId notificat send_closure(G()->td(), &Td::send_update, std::move(update)); } -void NotificationManager::flush_pending_notifications(NotificationGroupKey &group_key, NotificationGroup &group, - vector &pending_notifications) { +void NotificationManager::do_flush_pending_notifications(NotificationGroupKey &group_key, NotificationGroup &group, + vector &pending_notifications) { if (pending_notifications.empty()) { return; } @@ -275,22 +277,19 @@ void NotificationManager::flush_pending_notifications(NotificationGroupKey &grou pending_notifications.clear(); } -void NotificationManager::send_remove_group_update(NotificationGroupId group_id) { - CHECK(group_id.is_valid()); - auto group_it = get_group(group_id); - CHECK(group_it != groups_.end()); - - auto total_size = group_it->second.notifications.size(); +void NotificationManager::send_remove_group_update(const NotificationGroupKey &group_key, + const NotificationGroup &group) { + auto total_size = group.notifications.size(); auto removed_size = min(total_size, max_notification_group_size_); vector removed_notification_ids; removed_notification_ids.reserve(removed_size); for (size_t i = total_size - removed_size; i < total_size; i++) { - removed_notification_ids.push_back(group_it->second.notifications[i].notification_id.get()); + removed_notification_ids.push_back(group.notifications[i].notification_id.get()); } if (!removed_notification_ids.empty()) { send_update_notification_group(td_api::make_object( - group_id.get(), group_it->first.dialog_id.get(), group_it->first.dialog_id.get(), true, 0, + group_key.group_id.get(), group_key.dialog_id.get(), group_key.dialog_id.get(), true, 0, vector>(), std::move(removed_notification_ids))); } } @@ -354,7 +353,7 @@ void NotificationManager::flush_pending_notifications(NotificationGroupId group_ if (!was_updated) { if (last_group_key.last_notification_date != 0) { // need to remove last notification group to not exceed max_notification_group_size_ - send_remove_group_update(last_group_key.group_id); + send_remove_group_update(last_group_key, groups_[last_group_key]); } send_add_group_update(group_key, group); } @@ -367,13 +366,13 @@ void NotificationManager::flush_pending_notifications(NotificationGroupId group_ for (auto &pending_notification : group.pending_notifications) { if (notification_settings_dialog_id != pending_notification.settings_dialog_id || is_silent != pending_notification.is_silent) { - flush_pending_notifications(group_key, group, grouped_notifications); + do_flush_pending_notifications(group_key, group, grouped_notifications); notification_settings_dialog_id = pending_notification.settings_dialog_id; is_silent = pending_notification.is_silent; } grouped_notifications.push_back(std::move(pending_notification)); } - flush_pending_notifications(group_key, group, grouped_notifications); + do_flush_pending_notifications(group_key, group, grouped_notifications); } group.pending_notifications_flush_time = 0; @@ -459,7 +458,7 @@ void NotificationManager::on_notifications_removed( std::move(added_notifications), std::move(removed_notification_ids))); } else { // group needs to be removed - send_remove_group_update(group_key.group_id); + send_remove_group_update(group_key, group); if (last_group_key.last_notification_date != 0) { // need to add new last notification group send_add_group_update(last_group_key, groups_[last_group_key]); @@ -613,12 +612,15 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id vector removed_notification_ids; if (is_found && notification_delete_end + max_notification_group_size_ > old_group_size) { - for (size_t i = old_group_size; i < notification_delete_end + max_notification_group_size_; i++) { - removed_notification_ids.push_back( - group_it->second.notifications[i - max_notification_group_size_].notification_id.get()); + for (size_t i = old_group_size >= max_notification_group_size_ ? old_group_size - max_notification_group_size_ : 0; + i < notification_delete_end; i++) { + removed_notification_ids.push_back(group_it->second.notifications[i].notification_id.get()); } } + if (group_it->second.total_count == new_total_count) { + new_total_count = -1; + } if (new_total_count != -1) { group_it->second.total_count = new_total_count; } diff --git a/td/telegram/NotificationManager.h b/td/telegram/NotificationManager.h index b096783c3..b4c514f29 100644 --- a/td/telegram/NotificationManager.h +++ b/td/telegram/NotificationManager.h @@ -145,14 +145,14 @@ class NotificationManager : public Actor { NotificationGroupKey get_last_updated_group_key() const; - void send_remove_group_update(NotificationGroupId group_id); + void send_remove_group_update(const NotificationGroupKey &group_key, const NotificationGroup &group); void send_add_group_update(const NotificationGroupKey &group_key, const NotificationGroup &group); int32 get_notification_delay_ms(DialogId dialog_id, const PendingNotification ¬ification) const; - void flush_pending_notifications(NotificationGroupKey &group_key, NotificationGroup &group, - vector &pending_notifications); + void do_flush_pending_notifications(NotificationGroupKey &group_key, NotificationGroup &group, + vector &pending_notifications); void flush_pending_notifications(NotificationGroupId group_id);