Reload message reactions every 15 seconds.

This commit is contained in:
levlam 2022-03-07 15:20:22 +03:00
parent c5908619c2
commit 8f5bac2fe0
2 changed files with 99 additions and 8 deletions

View File

@ -5996,6 +5996,9 @@ MessagesManager::MessagesManager(Td *td, ActorShared<> parent)
preload_folder_dialog_list_timeout_.set_callback(on_preload_folder_dialog_list_timeout_callback);
preload_folder_dialog_list_timeout_.set_callback_data(static_cast<void *>(this));
update_viewed_messages_timeout_.set_callback(on_update_viewed_messages_timeout_callback);
update_viewed_messages_timeout_.set_callback_data(static_cast<void *>(this));
}
MessagesManager::~MessagesManager() = default;
@ -6127,6 +6130,16 @@ void MessagesManager::on_preload_folder_dialog_list_timeout_callback(void *messa
FolderId(narrow_cast<int32>(folder_id_int)));
}
void MessagesManager::on_update_viewed_messages_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int) {
if (G()->close_flag()) {
return;
}
auto messages_manager = static_cast<MessagesManager *>(messages_manager_ptr);
send_closure_later(messages_manager->actor_id(messages_manager), &MessagesManager::on_update_viewed_messages_timeout,
DialogId(dialog_id_int));
}
BufferSlice MessagesManager::get_dialog_database_value(const Dialog *d) {
// can't use log_event_store, because it tries to parse stored Dialog
LogEventStorerCalcLength storer_calc_length;
@ -8606,6 +8619,30 @@ vector<string> MessagesManager::get_message_active_reactions(const Dialog *d, co
return get_dialog_active_reactions(d);
}
bool MessagesManager::need_poll_dialog_message_reactions(const Dialog *d) {
CHECK(d != nullptr);
switch (d->dialog_id.get_type()) {
case DialogType::User:
case DialogType::SecretChat:
return false;
case DialogType::Chat:
case DialogType::Channel:
return (d->available_reactions_generation & 1) == 0;
default:
UNREACHABLE();
return {};
}
}
bool MessagesManager::need_poll_message_reactions(const Dialog *d, const Message *m) {
CHECK(m != nullptr);
if (!m->message_id.is_valid() || !m->message_id.is_server()) {
return false;
}
return need_poll_dialog_message_reactions(d) &&
(m->reactions != nullptr || m->available_reactions_generation != d->available_reactions_generation);
}
void MessagesManager::queue_message_reactions_reload(FullMessageId full_message_id) {
auto dialog_id = full_message_id.get_dialog_id();
CHECK(dialog_id.is_valid());
@ -12889,6 +12926,42 @@ void MessagesManager::on_update_dialog_online_member_count_timeout(DialogId dial
}
}
void MessagesManager::on_update_viewed_messages_timeout(DialogId dialog_id) {
if (G()->close_flag()) {
return;
}
LOG(INFO) << "Expired timeout for updating of recently viewed messages in " << dialog_id;
Dialog *d = get_dialog(dialog_id);
CHECK(d != nullptr);
if (!d->is_opened) {
return;
}
auto it = dialog_viewed_messages_.find(dialog_id);
if (it == dialog_viewed_messages_.end()) {
return;
}
if (need_poll_dialog_message_reactions(d)) {
auto &info = it->second;
CHECK(info != nullptr);
vector<MessageId> reaction_message_ids;
for (auto &message_it : info->message_id_to_view_id) {
const Message *m = get_message_force(d, message_it.first, "on_update_viewed_messages_timeout");
CHECK(m != nullptr);
CHECK(m->message_id.is_valid());
if (need_poll_message_reactions(d, m)) {
reaction_message_ids.push_back(m->message_id);
}
}
queue_message_reactions_reload(dialog_id, reaction_message_ids);
}
update_viewed_messages_timeout_.add_timeout_in(dialog_id.get(), UPDATE_VIEWED_MESSAGES_PERIOD);
}
MessageId MessagesManager::get_message_id(const tl_object_ptr<telegram_api::Message> &message_ptr, bool is_scheduled) {
switch (message_ptr->get_id()) {
case telegram_api::messageEmpty::ID: {
@ -16269,8 +16342,8 @@ void MessagesManager::on_message_deleted(Dialog *d, Message *m, bool is_permanen
}
}
if (d->is_opened) {
auto it = dialog_viewed_messages.find(d->dialog_id);
if (it != dialog_viewed_messages.end()) {
auto it = dialog_viewed_messages_.find(d->dialog_id);
if (it != dialog_viewed_messages_.end()) {
auto &info = it->second;
CHECK(info != nullptr);
auto message_it = info->message_id_to_view_id.find(m->message_id);
@ -20627,6 +20700,7 @@ Status MessagesManager::view_messages(DialogId dialog_id, MessageId top_thread_m
MessageId max_message_id; // max server or local viewed message_id
vector<MessageId> read_content_message_ids;
vector<MessageId> new_viewed_message_ids;
vector<MessageId> viewed_reaction_message_ids;
for (auto message_id : message_ids) {
if (!message_id.is_valid()) {
continue;
@ -20673,13 +20747,16 @@ Status MessagesManager::view_messages(DialogId dialog_id, MessageId top_thread_m
}
if (m->message_id.is_server() && d->is_opened) {
auto &info = dialog_viewed_messages[dialog_id];
auto &info = dialog_viewed_messages_[dialog_id];
if (info == nullptr) {
info = make_unique<ViewedMessagesInfo>();
}
auto &view_id = info->message_id_to_view_id[message_id];
if (view_id == 0) {
new_viewed_message_ids.push_back(message_id);
if (need_poll_message_reactions(d, m)) {
viewed_reaction_message_ids.push_back(message_id);
}
} else {
info->recently_viewed_messages.erase(view_id);
}
@ -20700,7 +20777,7 @@ Status MessagesManager::view_messages(DialogId dialog_id, MessageId top_thread_m
}
if (!new_viewed_message_ids.empty()) {
LOG(INFO) << "Have new viewed " << new_viewed_message_ids;
auto &info = dialog_viewed_messages[dialog_id];
auto &info = dialog_viewed_messages_[dialog_id];
CHECK(info != nullptr);
CHECK(info->message_id_to_view_id.size() == info->recently_viewed_messages.size());
constexpr size_t MAX_RECENTLY_VIEWED_MESSAGES = 50;
@ -20709,7 +20786,10 @@ Status MessagesManager::view_messages(DialogId dialog_id, MessageId top_thread_m
info->message_id_to_view_id.erase(it->second);
info->recently_viewed_messages.erase(it);
}
queue_message_reactions_reload(dialog_id, new_viewed_message_ids);
if (!viewed_reaction_message_ids.empty()) {
queue_message_reactions_reload(dialog_id, new_viewed_message_ids);
}
update_viewed_messages_timeout_.add_timeout_in(dialog_id.get(), UPDATE_VIEWED_MESSAGES_PERIOD);
}
if (!need_read) {
@ -21061,7 +21141,8 @@ void MessagesManager::close_dialog(Dialog *d) {
d->has_unload_timeout = true;
}
dialog_viewed_messages.erase(dialog_id);
dialog_viewed_messages_.erase(dialog_id);
update_viewed_messages_timeout_.cancel_timeout(dialog_id.get());
for (auto &it : d->pending_viewed_live_locations) {
auto live_location_task_id = it.second;

View File

@ -1772,7 +1772,8 @@ class MessagesManager final : public Actor {
static constexpr int32 MIN_READ_HISTORY_DELAY = 3; // seconds
static constexpr int32 MAX_SAVE_DIALOG_DELAY = 0; // seconds
static constexpr int32 LIVE_LOCATION_VIEW_PERIOD = 60; // seconds, server-side limit
static constexpr int32 LIVE_LOCATION_VIEW_PERIOD = 60; // seconds, server-side limit
static constexpr int32 UPDATE_VIEWED_MESSAGES_PERIOD = 15; // seconds
static constexpr int32 USERNAME_CACHE_EXPIRE_TIME = 3 * 86400;
static constexpr int32 USERNAME_CACHE_EXPIRE_TIME_SHORT = 900;
@ -2188,6 +2189,8 @@ class MessagesManager final : public Actor {
void on_update_dialog_online_member_count_timeout(DialogId dialog_id);
void on_update_viewed_messages_timeout(DialogId dialog_id);
bool delete_newer_server_messages_at_the_end(Dialog *d, MessageId max_message_id);
template <class T, class It>
@ -2645,6 +2648,10 @@ class MessagesManager final : public Actor {
vector<string> get_message_active_reactions(const Dialog *d, const Message *m) const;
static bool need_poll_dialog_message_reactions(const Dialog *d);
static bool need_poll_message_reactions(const Dialog *d, const Message *m);
void queue_message_reactions_reload(FullMessageId full_message_id);
void queue_message_reactions_reload(DialogId dialog_id, const vector<MessageId> &message_ids);
@ -3111,6 +3118,8 @@ class MessagesManager final : public Actor {
static void on_preload_folder_dialog_list_timeout_callback(void *messages_manager_ptr, int64 folder_id_int);
static void on_update_viewed_messages_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int);
void load_secret_thumbnail(FileId thumbnail_file_id);
void on_upload_media(FileId file_id, tl_object_ptr<telegram_api::InputFile> input_file,
@ -3549,6 +3558,7 @@ class MessagesManager final : public Actor {
MultiTimeout active_dialog_action_timeout_{"ActiveDialogActionTimeout"};
MultiTimeout update_dialog_online_member_count_timeout_{"UpdateDialogOnlineMemberCountTimeout"};
MultiTimeout preload_folder_dialog_list_timeout_{"PreloadFolderDialogListTimeout"};
MultiTimeout update_viewed_messages_timeout_{"UpdateViewedMessagesTimeout"};
Timeout reload_dialog_filters_timeout_;
@ -3639,7 +3649,7 @@ class MessagesManager final : public Actor {
std::map<uint64, MessageId> recently_viewed_messages;
uint64 current_view_id = 0;
};
FlatHashMap<DialogId, unique_ptr<ViewedMessagesInfo>, DialogIdHash> dialog_viewed_messages;
FlatHashMap<DialogId, unique_ptr<ViewedMessagesInfo>, DialogIdHash> dialog_viewed_messages_;
struct OnlineMemberCountInfo {
int32 online_member_count = 0;