Send updateMessageContent when WebPage is changed.

GitOrigin-RevId: 8e20fd788a4f5333f686d96241459774319ac8d7
This commit is contained in:
levlam 2020-01-27 02:55:18 +03:00
parent 9f2870a5a0
commit 129f96da69
6 changed files with 98 additions and 112 deletions

View File

@ -2807,16 +2807,11 @@ bool get_message_content_poll_is_anonymous(const Td *td, const MessageContent *c
} }
} }
WebPageId get_message_content_web_page_id(const MessageContent *content) { void remove_message_content_web_page(MessageContent *content) {
if (content->get_type() == MessageContentType::Text) {
return static_cast<const MessageText *>(content)->web_page_id;
}
return WebPageId();
}
void set_message_content_web_page_id(MessageContent *content, WebPageId web_page_id) {
CHECK(content->get_type() == MessageContentType::Text); CHECK(content->get_type() == MessageContentType::Text);
static_cast<MessageText *>(content)->web_page_id = web_page_id; auto &web_page_id = static_cast<MessageText *>(content)->web_page_id;
CHECK(web_page_id.is_valid());
web_page_id = WebPageId();
} }
void set_message_content_poll_answer(Td *td, const MessageContent *content, FullMessageId full_message_id, void set_message_content_poll_answer(Td *td, const MessageContent *content, FullMessageId full_message_id,
@ -3476,6 +3471,9 @@ bool merge_message_content_file_id(Td *td, MessageContent *message_content, File
void register_message_content(Td *td, const MessageContent *content, FullMessageId full_message_id) { void register_message_content(Td *td, const MessageContent *content, FullMessageId full_message_id) {
switch (content->get_type()) { switch (content->get_type()) {
case MessageContentType::Text:
return td->web_pages_manager_->register_web_page(static_cast<const MessageText *>(content)->web_page_id,
full_message_id);
case MessageContentType::Poll: case MessageContentType::Poll:
return td->poll_manager_->register_poll(static_cast<const MessagePoll *>(content)->poll_id, full_message_id); return td->poll_manager_->register_poll(static_cast<const MessagePoll *>(content)->poll_id, full_message_id);
default: default:
@ -3489,6 +3487,12 @@ void reregister_message_content(Td *td, const MessageContent *old_content, const
auto new_content_type = new_content->get_type(); auto new_content_type = new_content->get_type();
if (old_content_type == new_content_type) { if (old_content_type == new_content_type) {
switch (old_content_type) { switch (old_content_type) {
case MessageContentType::Text:
if (static_cast<const MessageText *>(old_content)->web_page_id ==
static_cast<const MessageText *>(new_content)->web_page_id) {
return;
}
break;
case MessageContentType::Poll: case MessageContentType::Poll:
if (static_cast<const MessagePoll *>(old_content)->poll_id == if (static_cast<const MessagePoll *>(old_content)->poll_id ==
static_cast<const MessagePoll *>(new_content)->poll_id) { static_cast<const MessagePoll *>(new_content)->poll_id) {
@ -3505,6 +3509,9 @@ void reregister_message_content(Td *td, const MessageContent *old_content, const
void unregister_message_content(Td *td, const MessageContent *content, FullMessageId full_message_id) { void unregister_message_content(Td *td, const MessageContent *content, FullMessageId full_message_id) {
switch (content->get_type()) { switch (content->get_type()) {
case MessageContentType::Text:
return td->web_pages_manager_->unregister_web_page(static_cast<const MessageText *>(content)->web_page_id,
full_message_id);
case MessageContentType::Poll: case MessageContentType::Poll:
return td->poll_manager_->unregister_poll(static_cast<const MessagePoll *>(content)->poll_id, full_message_id); return td->poll_manager_->unregister_poll(static_cast<const MessagePoll *>(content)->poll_id, full_message_id);
default: default:

View File

@ -186,9 +186,7 @@ bool get_message_content_poll_is_closed(const Td *td, const MessageContent *cont
bool get_message_content_poll_is_anonymous(const Td *td, const MessageContent *content); bool get_message_content_poll_is_anonymous(const Td *td, const MessageContent *content);
WebPageId get_message_content_web_page_id(const MessageContent *content); void remove_message_content_web_page(MessageContent *content);
void set_message_content_web_page_id(MessageContent *content, WebPageId web_page_id);
void set_message_content_poll_answer(Td *td, const MessageContent *content, FullMessageId full_message_id, void set_message_content_poll_answer(Td *td, const MessageContent *content, FullMessageId full_message_id,
vector<int32> &&option_ids, Promise<Unit> &&promise); vector<int32> &&option_ids, Promise<Unit> &&promise);

View File

@ -11888,43 +11888,21 @@ void MessagesManager::on_update_sent_text_message(int64 random_id,
} }
} }
void MessagesManager::on_update_message_web_page(FullMessageId full_message_id, bool have_web_page) { void MessagesManager::delete_pending_message_web_page(FullMessageId full_message_id) {
waiting_for_web_page_messages_.erase(full_message_id);
auto dialog_id = full_message_id.get_dialog_id(); auto dialog_id = full_message_id.get_dialog_id();
Dialog *d = get_dialog(dialog_id); Dialog *d = get_dialog(dialog_id);
if (d == nullptr) { CHECK(d != nullptr);
LOG(INFO) << "Can't find " << dialog_id;
// dialog can be not yet added
return;
}
Message *m = get_message(d, full_message_id.get_message_id()); Message *m = get_message(d, full_message_id.get_message_id());
if (m == nullptr) { CHECK(m != nullptr);
// message can be already deleted
return;
}
CHECK(m->date > 0);
MessageContent *content = m->content.get(); MessageContent *content = m->content.get();
auto old_web_page_id = get_message_content_web_page_id(content); unregister_message_content(td_, content, full_message_id);
if (!old_web_page_id.is_valid()) { remove_message_content_web_page(content);
// webpage has already been received as empty register_message_content(td_, content, full_message_id);
LOG_IF(ERROR, have_web_page) << "Receive earlier not received web page";
return;
}
CHECK(content->get_type() == MessageContentType::Text);
if (!have_web_page) { // don't need to send an updateMessageContent, because the web page was pending
unregister_message_content(td_, content, full_message_id);
set_message_content_web_page_id(content, WebPageId());
register_message_content(td_, content, full_message_id);
// don't need to send an update, because the web page was pending on_message_changed(d, m, false, "delete_pending_message_web_page");
on_message_changed(d, m, false, "on_update_message_web_page");
return;
}
send_update_message_content(dialog_id, m->message_id, content, m->date, m->is_content_secret,
"on_update_message_web_page");
} }
void MessagesManager::on_get_dialogs(FolderId folder_id, vector<tl_object_ptr<telegram_api::Dialog>> &&dialog_folders, void MessagesManager::on_get_dialogs(FolderId folder_id, vector<tl_object_ptr<telegram_api::Dialog>> &&dialog_folders,
@ -12324,7 +12302,6 @@ bool MessagesManager::can_unload_message(const Dialog *d, const Message *m) cons
CHECK(m->message_id.is_valid()); CHECK(m->message_id.is_valid());
// don't want to unload messages from opened dialogs // don't want to unload messages from opened dialogs
// don't want to unload messages to which there are replies in yet unsent messages // don't want to unload messages to which there are replies in yet unsent messages
// don't want to unload messages with pending web pages
// don't want to unload message with active reply markup // don't want to unload message with active reply markup
// don't want to unload pinned message // don't want to unload pinned message
// don't want to unload last edited message, because server can send updateEditChannelMessage again // don't want to unload last edited message, because server can send updateEditChannelMessage again
@ -12334,9 +12311,8 @@ bool MessagesManager::can_unload_message(const Dialog *d, const Message *m) cons
return !d->is_opened && m->message_id != d->last_message_id && m->message_id != d->last_database_message_id && return !d->is_opened && m->message_id != d->last_message_id && m->message_id != d->last_database_message_id &&
!m->message_id.is_yet_unsent() && active_live_location_full_message_ids_.count(full_message_id) == 0 && !m->message_id.is_yet_unsent() && active_live_location_full_message_ids_.count(full_message_id) == 0 &&
replied_by_yet_unsent_messages_.count(full_message_id) == 0 && m->edited_content == nullptr && replied_by_yet_unsent_messages_.count(full_message_id) == 0 && m->edited_content == nullptr &&
waiting_for_web_page_messages_.count(full_message_id) == 0 && d->suffix_load_queries_.empty() && d->suffix_load_queries_.empty() && m->message_id != d->reply_markup_message_id &&
m->message_id != d->reply_markup_message_id && m->message_id != d->pinned_message_id && m->message_id != d->pinned_message_id && m->message_id != d->last_edited_message_id;
m->message_id != d->last_edited_message_id;
} }
void MessagesManager::unload_message(Dialog *d, MessageId message_id) { void MessagesManager::unload_message(Dialog *d, MessageId message_id) {
@ -17152,12 +17128,6 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId
message->from_database = true; message->from_database = true;
auto old_message = get_message(d, message->message_id); auto old_message = get_message(d, message->message_id);
if (old_message == nullptr) {
auto web_page_id = get_message_content_web_page_id(message->content.get());
if (web_page_id.is_valid()) {
td_->web_pages_manager_->have_web_page_force(web_page_id);
}
}
Message *m = old_message ? old_message Message *m = old_message ? old_message
: add_message_to_dialog(d, std::move(message), false, &need_update, : add_message_to_dialog(d, std::move(message), false, &need_update,
&need_update_dialog_pos, "on_get_history_from_database"); &need_update_dialog_pos, "on_get_history_from_database");
@ -17463,10 +17433,6 @@ void MessagesManager::on_get_scheduled_messages_from_database(DialogId dialog_id
continue; continue;
} }
auto web_page_id = get_message_content_web_page_id(message->content.get());
if (web_page_id.is_valid()) {
td_->web_pages_manager_->have_web_page_force(web_page_id);
}
bool need_update = false; bool need_update = false;
Message *m = add_scheduled_message_to_dialog(d, std::move(message), false, &need_update, Message *m = add_scheduled_message_to_dialog(d, std::move(message), false, &need_update,
"on_get_scheduled_messages_from_database"); "on_get_scheduled_messages_from_database");
@ -25948,13 +25914,6 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
return nullptr; return nullptr;
} }
auto web_page_id = get_message_content_web_page_id(message->content.get());
if (web_page_id.is_valid() && !td_->web_pages_manager_->have_web_page(web_page_id)) {
waiting_for_web_page_messages_.emplace(dialog_id, message_id);
send_closure(G()->web_pages_manager(), &WebPagesManager::wait_for_pending_web_page,
FullMessageId{dialog_id, message_id}, web_page_id);
}
if (*need_update && message_id <= d->last_new_message_id) { if (*need_update && message_id <= d->last_new_message_id) {
*need_update = false; *need_update = false;
} }
@ -26527,13 +26486,6 @@ MessagesManager::Message *MessagesManager::add_scheduled_message_to_dialog(Dialo
return nullptr; return nullptr;
} }
auto web_page_id = get_message_content_web_page_id(message->content.get());
if (web_page_id.is_valid() && !td_->web_pages_manager_->have_web_page(web_page_id)) {
waiting_for_web_page_messages_.emplace(dialog_id, message_id);
send_closure(G()->web_pages_manager(), &WebPagesManager::wait_for_pending_web_page,
FullMessageId{dialog_id, message_id}, web_page_id);
}
{ {
Message *m = message->from_database ? get_message(d, message_id) Message *m = message->from_database ? get_message(d, message_id)
: get_message_force(d, message_id, "add_scheduled_message_to_dialog"); : get_message_force(d, message_id, "add_scheduled_message_to_dialog");

View File

@ -266,7 +266,7 @@ class MessagesManager : public Actor {
void on_update_sent_text_message(int64 random_id, tl_object_ptr<telegram_api::MessageMedia> message_media, void on_update_sent_text_message(int64 random_id, tl_object_ptr<telegram_api::MessageMedia> message_media,
vector<tl_object_ptr<telegram_api::MessageEntity>> &&entities); vector<tl_object_ptr<telegram_api::MessageEntity>> &&entities);
void on_update_message_web_page(FullMessageId full_message_id, bool have_web_page); void delete_pending_message_web_page(FullMessageId full_message_id);
void on_get_dialogs(FolderId folder_id, vector<tl_object_ptr<telegram_api::Dialog>> &&dialog_folders, void on_get_dialogs(FolderId folder_id, vector<tl_object_ptr<telegram_api::Dialog>> &&dialog_folders,
int32 total_count, vector<tl_object_ptr<telegram_api::Message>> &&messages, int32 total_count, vector<tl_object_ptr<telegram_api::Message>> &&messages,
@ -2626,8 +2626,6 @@ class MessagesManager : public Actor {
std::unordered_map<FullMessageId, int32, FullMessageIdHash> replied_by_yet_unsent_messages_; std::unordered_map<FullMessageId, int32, FullMessageIdHash> replied_by_yet_unsent_messages_;
std::unordered_set<FullMessageId, FullMessageIdHash> waiting_for_web_page_messages_;
struct ActiveDialogAction { struct ActiveDialogAction {
UserId user_id; UserId user_id;
int32 action_id; int32 action_id;

View File

@ -10,6 +10,7 @@
#include "td/telegram/AnimationsManager.h" #include "td/telegram/AnimationsManager.h"
#include "td/telegram/AudiosManager.h" #include "td/telegram/AudiosManager.h"
#include "td/telegram/AuthManager.h"
#include "td/telegram/Document.h" #include "td/telegram/Document.h"
#include "td/telegram/Document.hpp" #include "td/telegram/Document.hpp"
#include "td/telegram/DocumentsManager.h" #include "td/telegram/DocumentsManager.h"
@ -412,20 +413,10 @@ WebPageId WebPagesManager::on_get_web_page(tl_object_ptr<telegram_api::WebPage>
web_pages_.erase(web_page_id); web_pages_.erase(web_page_id);
} }
update_messages_content(web_page_id, false); on_web_page_changed(web_page_id, false);
if (!G()->parameters().use_message_db) { if (G()->parameters().use_message_db) {
// update_messages_content(web_page_id, false);
} else {
LOG(INFO) << "Delete " << web_page_id << " from database"; LOG(INFO) << "Delete " << web_page_id << " from database";
G()->td_db()->get_sqlite_pmc()->erase(get_web_page_database_key(web_page_id), Auto() G()->td_db()->get_sqlite_pmc()->erase(get_web_page_database_key(web_page_id), Auto());
/*
PromiseCreator::lambda([web_page_id](Result<> result) {
if (result.is_ok()) {
send_closure(G()->web_pages_manager(), &WebPagesManager::update_messages_content, web_page_id, false);
}
})
*/
);
G()->td_db()->get_sqlite_pmc()->erase(get_web_page_instant_view_database_key(web_page_id), Auto()); G()->td_db()->get_sqlite_pmc()->erase(get_web_page_instant_view_database_key(web_page_id), Auto());
} }
@ -555,13 +546,9 @@ void WebPagesManager::update_web_page(unique_ptr<WebPage> web_page, WebPageId we
on_get_web_page_by_url(page->url, web_page_id, from_database); on_get_web_page_by_url(page->url, web_page_id, from_database);
if (!is_changed) { if (is_changed && !from_database) {
return; on_web_page_changed(web_page_id, true);
}
update_messages_content(web_page_id, true);
if (!from_database) {
save_web_page(page.get(), web_page_id, from_binlog); save_web_page(page.get(), web_page_id, from_binlog);
} }
} }
@ -663,10 +650,37 @@ void WebPagesManager::on_get_web_page_by_url(const string &url, WebPageId web_pa
cached_web_page_id = web_page_id; cached_web_page_id = web_page_id;
} }
void WebPagesManager::wait_for_pending_web_page(FullMessageId full_message_id, WebPageId web_page_id) { void WebPagesManager::register_web_page(WebPageId web_page_id, FullMessageId full_message_id) {
LOG(INFO) << "Waiting for " << web_page_id << " needed in " << full_message_id; if (!web_page_id.is_valid()) {
pending_web_pages_[web_page_id].emplace(full_message_id); return;
pending_web_pages_timeout_.add_timeout_in(web_page_id.get(), 1.0); }
LOG(INFO) << "Register " << web_page_id << " from " << full_message_id;
bool is_inserted = web_page_messages_[web_page_id].insert(full_message_id).second;
CHECK(is_inserted);
if (!td_->auth_manager_->is_bot() && !have_web_page_force(web_page_id)) {
LOG(INFO) << "Waiting for " << web_page_id << " needed in " << full_message_id;
pending_web_pages_timeout_.add_timeout_in(web_page_id.get(), 1.0);
}
}
void WebPagesManager::unregister_web_page(WebPageId web_page_id, FullMessageId full_message_id) {
if (!web_page_id.is_valid()) {
return;
}
LOG(INFO) << "Unregister " << web_page_id << " from " << full_message_id;
auto &message_ids = web_page_messages_[web_page_id];
auto is_deleted = message_ids.erase(full_message_id);
CHECK(is_deleted);
if (message_ids.empty()) {
web_page_messages_.erase(web_page_id);
if (pending_get_web_pages_.count(web_page_id) == 0) {
pending_web_pages_timeout_.cancel_timeout(web_page_id.get());
}
}
} }
void WebPagesManager::on_get_web_page_preview_success(int64 request_id, const string &url, void WebPagesManager::on_get_web_page_preview_success(int64 request_id, const string &url,
@ -693,7 +707,6 @@ void WebPagesManager::on_get_web_page_preview_success(int64 request_id, const st
if (web_page_id.is_valid() && !have_web_page(web_page_id)) { if (web_page_id.is_valid() && !have_web_page(web_page_id)) {
pending_get_web_pages_[web_page_id].emplace(request_id, pending_get_web_pages_[web_page_id].emplace(request_id,
std::make_pair(url, std::move(promise))); // TODO MultiPromise ? std::make_pair(url, std::move(promise))); // TODO MultiPromise ?
pending_web_pages_timeout_.add_timeout_in(web_page_id.get(), 1.0);
return; return;
} }
@ -1163,15 +1176,26 @@ tl_object_ptr<td_api::webPageInstantView> WebPagesManager::get_web_page_instant_
web_page_instant_view->is_rtl, web_page_instant_view->is_full); web_page_instant_view->is_rtl, web_page_instant_view->is_full);
} }
void WebPagesManager::update_messages_content(WebPageId web_page_id, bool have_web_page) { void WebPagesManager::on_web_page_changed(WebPageId web_page_id, bool have_web_page) {
LOG(INFO) << "Update messages awaiting " << web_page_id; LOG(INFO) << "Updated " << web_page_id;
auto it = pending_web_pages_.find(web_page_id); auto it = web_page_messages_.find(web_page_id);
if (it != pending_web_pages_.end()) { if (it != web_page_messages_.end()) {
auto full_message_ids = std::move(it->second); vector<FullMessageId> full_message_ids;
pending_web_pages_.erase(it); for (auto full_message_id : it->second) {
full_message_ids.push_back(full_message_id);
}
CHECK(!full_message_ids.empty());
for (auto full_message_id : full_message_ids) { for (auto full_message_id : full_message_ids) {
send_closure_later(G()->messages_manager(), &MessagesManager::on_update_message_web_page, full_message_id, if (!have_web_page) {
have_web_page); td_->messages_manager_->delete_pending_message_web_page(full_message_id);
} else {
td_->messages_manager_->on_external_update_message_content(full_message_id);
}
}
if (have_web_page) {
CHECK(web_page_messages_[web_page_id].size() == full_message_ids.size());
} else {
CHECK(web_page_messages_.count(web_page_id) == 0);
} }
} }
auto get_it = pending_get_web_pages_.find(web_page_id); auto get_it = pending_get_web_pages_.find(web_page_id);
@ -1208,9 +1232,13 @@ void WebPagesManager::on_pending_web_page_timeout_callback(void *web_pages_manag
} }
void WebPagesManager::on_pending_web_page_timeout(WebPageId web_page_id) { void WebPagesManager::on_pending_web_page_timeout(WebPageId web_page_id) {
if (have_web_page(web_page_id)) {
return;
}
int32 count = 0; int32 count = 0;
auto it = pending_web_pages_.find(web_page_id); auto it = web_page_messages_.find(web_page_id);
if (it != pending_web_pages_.end()) { if (it != web_page_messages_.end()) {
vector<FullMessageId> full_message_ids; vector<FullMessageId> full_message_ids;
for (auto full_message_id : it->second) { for (auto full_message_id : it->second) {
full_message_ids.push_back(full_message_id); full_message_ids.push_back(full_message_id);
@ -1230,7 +1258,7 @@ void WebPagesManager::on_pending_web_page_timeout(WebPageId web_page_id) {
} }
} }
if (count == 0) { if (count == 0) {
LOG(WARNING) << "Have no messages waiting for " << web_page_id; LOG(WARNING) << "Have no messages and requests waiting for " << web_page_id;
} }
} }

View File

@ -13,7 +13,7 @@
#include "td/telegram/files/FileId.h" #include "td/telegram/files/FileId.h"
#include "td/telegram/files/FileSourceId.h" #include "td/telegram/files/FileSourceId.h"
#include "td/telegram/FullMessageId.h" #include "td/telegram/FullMessageId.h"
#include "td/telegram/Photo.h" #include "td/telegram/SecretInputMedia.h"
#include "td/telegram/WebPageId.h" #include "td/telegram/WebPageId.h"
#include "td/actor/actor.h" #include "td/actor/actor.h"
@ -47,7 +47,9 @@ class WebPagesManager : public Actor {
void on_get_web_page_by_url(const string &url, WebPageId web_page_id, bool from_database); void on_get_web_page_by_url(const string &url, WebPageId web_page_id, bool from_database);
void wait_for_pending_web_page(FullMessageId full_message_id, WebPageId web_page_id); void register_web_page(WebPageId web_page_id, FullMessageId full_message_id);
void unregister_web_page(WebPageId web_page_id, FullMessageId full_message_id);
bool have_web_page(WebPageId web_page_id) const; bool have_web_page(WebPageId web_page_id) const;
@ -111,7 +113,7 @@ class WebPagesManager : public Actor {
static bool need_use_old_instant_view(const WebPageInstantView &new_instant_view, static bool need_use_old_instant_view(const WebPageInstantView &new_instant_view,
const WebPageInstantView &old_instant_view); const WebPageInstantView &old_instant_view);
void update_messages_content(WebPageId web_page_id, bool have_web_page); void on_web_page_changed(WebPageId web_page_id, bool have_web_page);
const WebPage *get_web_page(WebPageId web_page_id) const; const WebPage *get_web_page(WebPageId web_page_id) const;
@ -181,7 +183,8 @@ class WebPagesManager : public Actor {
}; };
std::unordered_map<WebPageId, PendingWebPageInstantViewQueries, WebPageIdHash> load_web_page_instant_view_queries_; std::unordered_map<WebPageId, PendingWebPageInstantViewQueries, WebPageIdHash> load_web_page_instant_view_queries_;
std::unordered_map<WebPageId, std::unordered_set<FullMessageId, FullMessageIdHash>, WebPageIdHash> pending_web_pages_; std::unordered_map<WebPageId, std::unordered_set<FullMessageId, FullMessageIdHash>, WebPageIdHash> web_page_messages_;
std::unordered_map<WebPageId, std::unordered_map<int64, std::pair<string, Promise<Unit>>>, WebPageIdHash> std::unordered_map<WebPageId, std::unordered_map<int64, std::pair<string, Promise<Unit>>>, WebPageIdHash>
pending_get_web_pages_; pending_get_web_pages_;