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())) { 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"; << d->pending_new_message_notifications.size() << " already waiting messages";
if (d->pending_new_message_notifications.empty()) { if (d->pending_new_message_notifications.empty()) {
create_actor<SleepActor>( create_actor<SleepActor>(
"FlushPendingNewMessageNotificationsSleepActor", 5.0, "FlushPendingNewMessageNotificationsSleepActor", 5.0,
PromiseCreator::lambda([actor_id = actor_id(this), dialog_id = d->dialog_id](Result<Unit> result) { 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, DialogId());
send_closure(actor_id, &MessagesManager::flush_pending_new_message_notifications, dialog_id);
})) }))
.release(); .release();
} }
d->pending_new_message_notifications.push_back(m->message_id); auto last_settings_dialog_id =
auto promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_id = d->dialog_id](Result<Unit> result) { (d->pending_new_message_notifications.empty() ? DialogId() : d->pending_new_message_notifications.back().first);
VLOG(notifications) << "Flush pending notifications in " << dialog_id d->pending_new_message_notifications.emplace_back((have_settings ? DialogId() : settings_dialog_id), m->message_id);
<< " because of received notification settings"; if (!have_settings && last_settings_dialog_id != settings_dialog_id) {
send_closure(actor_id, &MessagesManager::flush_pending_new_message_notifications, 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)) { if (settings_dialog == nullptr && have_input_peer(settings_dialog_id, AccessRights::Read)) {
force_create_dialog(settings_dialog_id, "add_new_message_notification"); 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 { } else {
send_get_dialog_query(settings_dialog_id, std::move(promise)); send_get_dialog_query(settings_dialog_id, std::move(promise));
} }
}
return; 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)); 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); auto d = get_dialog(dialog_id);
CHECK(d != nullptr); CHECK(d != nullptr);
if (d->pending_new_message_notifications.empty()) { if (d->pending_new_message_notifications.empty()) {
return; return;
} }
auto message_ids = std::move(d->pending_new_message_notifications); for (auto &it : d->pending_new_message_notifications) {
reset_to_empty(d->pending_new_message_notifications); if (it.first == settings_dialog_id || !settings_dialog_id.is_valid()) {
for (auto message_id : message_ids) { it.first = DialogId();
auto m = get_message(d, message_id); }
}
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) { if (m != nullptr) {
add_new_message_notification(d, m, true); 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::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; string client_data;
@ -1459,7 +1459,7 @@ class MessagesManager : public Actor {
void add_new_message_notification(Dialog *d, Message *m, bool force); 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; 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); 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 { 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)); 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) { vector<PendingNotification> &pending_notifications) {
if (pending_notifications.empty()) { if (pending_notifications.empty()) {
return; return;
@ -275,22 +277,19 @@ void NotificationManager::flush_pending_notifications(NotificationGroupKey &grou
pending_notifications.clear(); pending_notifications.clear();
} }
void NotificationManager::send_remove_group_update(NotificationGroupId group_id) { void NotificationManager::send_remove_group_update(const NotificationGroupKey &group_key,
CHECK(group_id.is_valid()); const NotificationGroup &group) {
auto group_it = get_group(group_id); auto total_size = group.notifications.size();
CHECK(group_it != groups_.end());
auto total_size = group_it->second.notifications.size();
auto removed_size = min(total_size, max_notification_group_size_); auto removed_size = min(total_size, max_notification_group_size_);
vector<int32> removed_notification_ids; vector<int32> removed_notification_ids;
removed_notification_ids.reserve(removed_size); removed_notification_ids.reserve(removed_size);
for (size_t i = total_size - removed_size; i < total_size; i++) { 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()) { if (!removed_notification_ids.empty()) {
send_update_notification_group(td_api::make_object<td_api::updateNotificationGroup>( 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))); 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 (!was_updated) {
if (last_group_key.last_notification_date != 0) { if (last_group_key.last_notification_date != 0) {
// need to remove last notification group to not exceed max_notification_group_size_ // 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); 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) { for (auto &pending_notification : group.pending_notifications) {
if (notification_settings_dialog_id != pending_notification.settings_dialog_id || if (notification_settings_dialog_id != pending_notification.settings_dialog_id ||
is_silent != pending_notification.is_silent) { 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; notification_settings_dialog_id = pending_notification.settings_dialog_id;
is_silent = pending_notification.is_silent; is_silent = pending_notification.is_silent;
} }
grouped_notifications.push_back(std::move(pending_notification)); 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; group.pending_notifications_flush_time = 0;
@ -459,7 +458,7 @@ void NotificationManager::on_notifications_removed(
std::move(added_notifications), std::move(removed_notification_ids))); std::move(added_notifications), std::move(removed_notification_ids)));
} else { } else {
// group needs to be removed // 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) { if (last_group_key.last_notification_date != 0) {
// need to add new last notification group // need to add new last notification group
send_add_group_update(last_group_key, groups_[last_group_key]); 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; vector<int32> removed_notification_ids;
if (is_found && notification_delete_end + max_notification_group_size_ > old_group_size) { 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++) { for (size_t i = old_group_size >= max_notification_group_size_ ? old_group_size - max_notification_group_size_ : 0;
removed_notification_ids.push_back( i < notification_delete_end; i++) {
group_it->second.notifications[i - max_notification_group_size_].notification_id.get()); 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) { if (new_total_count != -1) {
group_it->second.total_count = new_total_count; 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; 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); void send_add_group_update(const NotificationGroupKey &group_key, const NotificationGroup &group);
int32 get_notification_delay_ms(DialogId dialog_id, const PendingNotification &notification) const; 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); vector<PendingNotification> &pending_notifications);
void flush_pending_notifications(NotificationGroupId group_id); void flush_pending_notifications(NotificationGroupId group_id);