Fix flush_pending_new_message_notifications.

GitOrigin-RevId: b3b2e75d95760c2f57e71a4eb66da0674ea56da0
This commit is contained in:
levlam 2018-11-21 15:23:43 +03:00
parent 28da401d87
commit b666f554f4
4 changed files with 66 additions and 46 deletions

View File

@ -17466,22 +17466,25 @@ 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 "
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<SleepActor>(
"FlushPendingNewMessageNotificationsSleepActor", 5.0,
PromiseCreator::lambda([actor_id = actor_id(this), dialog_id = d->dialog_id](Result<Unit> 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<Unit> 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);
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<Unit> 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");
@ -17492,6 +17495,7 @@ void MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f
} 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);
}
}

View File

@ -905,7 +905,7 @@ class MessagesManager : public Actor {
std::unordered_set<MessageId, MessageIdHash> deleted_message_ids;
std::vector<MessageId> pending_new_message_notifications;
std::vector<std::pair<DialogId, MessageId>> 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;

View File

@ -33,7 +33,9 @@ void NotificationManager::on_flush_pending_notifications_timeout_callback(void *
}
auto notification_manager = static_cast<NotificationManager *>(notification_manager_ptr);
notification_manager->flush_pending_notifications(NotificationGroupId(narrow_cast<int32>(group_id_int)));
send_closure_later(notification_manager->actor_id(notification_manager),
&NotificationManager::flush_pending_notifications,
NotificationGroupId(narrow_cast<int32>(group_id_int)));
}
bool NotificationManager::is_disabled() const {
@ -221,7 +223,7 @@ 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,
void NotificationManager::do_flush_pending_notifications(NotificationGroupKey &group_key, NotificationGroup &group,
vector<PendingNotification> &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<int32> 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<td_api::updateNotificationGroup>(
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<td_api::object_ptr<td_api::notification>>(), 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<int32> 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;
}

View File

@ -145,13 +145,13 @@ 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 &notification) const;
void flush_pending_notifications(NotificationGroupKey &group_key, NotificationGroup &group,
void do_flush_pending_notifications(NotificationGroupKey &group_key, NotificationGroup &group,
vector<PendingNotification> &pending_notifications);
void flush_pending_notifications(NotificationGroupId group_id);