From 4d7afaedbbea44d238c44dc7807eed270ec34ba5 Mon Sep 17 00:00:00 2001 From: levlam Date: Tue, 1 Mar 2022 23:09:40 +0300 Subject: [PATCH] Improve DownloadManager initialization. --- td/telegram/DownloadManager.cpp | 67 ++++++++++++++++------------ td/telegram/DownloadManager.h | 2 +- td/telegram/FileReferenceManager.cpp | 6 +-- td/telegram/FileReferenceManager.h | 7 +-- td/telegram/MessagesManager.cpp | 11 ++--- td/telegram/MessagesManager.h | 4 +- 6 files changed, 48 insertions(+), 49 deletions(-) diff --git a/td/telegram/DownloadManager.cpp b/td/telegram/DownloadManager.cpp index 6ae11cf51..85ce382de 100644 --- a/td/telegram/DownloadManager.cpp +++ b/td/telegram/DownloadManager.cpp @@ -160,30 +160,38 @@ class DownloadManagerImpl final : public DownloadManager { } void hints_synchronized(Result) { + if (G()->close_flag()) { + return; + } + LOG(INFO) << "DownloadManager: hints are synchronized"; - hints_state_ = 2; + is_search_inited_ = true; } + void search(string query, bool only_active, bool only_completed, string offset, int32 limit, Promise> promise) final { return do_search(std::move(query), only_active, only_completed, std::move(offset), limit, std::move(promise), Unit{}); } + void do_search(string query, bool only_active, bool only_completed, string offset, int32 limit, Promise> promise, Result) { + TRY_STATUS_PROMISE(promise, G()->close_status()); TRY_STATUS_PROMISE(promise, check_is_active()); - if (hints_state_ < 2) { + if (!is_search_inited_) { Promise lock; - if (hints_state_ == 0) { - mpas_.add_promise(promise_send_closure(actor_id(this), &DownloadManagerImpl::hints_synchronized)); - mpas_.set_ignore_errors(true); - lock = mpas_.get_promise(); + if (load_search_text_multipromise_.promise_count() == 0) { + load_search_text_multipromise_.add_promise( + promise_send_closure(actor_id(this), &DownloadManagerImpl::hints_synchronized)); + load_search_text_multipromise_.set_ignore_errors(true); + lock = load_search_text_multipromise_.get_promise(); prepare_hints(); - hints_state_ = 1; } - mpas_.add_promise(promise_send_closure(actor_id(this), &DownloadManagerImpl::do_search, std::move(query), - only_active, only_completed, std::move(offset), limit, - std::move(promise))); + load_search_text_multipromise_.add_promise(promise_send_closure(actor_id(this), &DownloadManagerImpl::do_search, + std::move(query), only_active, only_completed, + std::move(offset), limit, std::move(promise))); + lock.set_value(Unit()); return; } @@ -300,12 +308,11 @@ class DownloadManagerImpl final : public DownloadManager { Counters counters_; Counters sent_counters_; - bool is_synchonized_{false}; bool is_started_{false}; + bool is_search_inited_{false}; int64 max_download_id_{0}; uint64 last_link_token_{0}; - int hints_state_; - MultiPromiseActorSafe mpas_{"DownloadManager: hints"}; + MultiPromiseActor load_search_text_multipromise_{"LoadFileSearchTextMultiPromiseActor"}; int64 next_download_id() { return ++max_download_id_; @@ -344,7 +351,7 @@ class DownloadManagerImpl final : public DownloadManager { if (is_started_) { return; } - is_started_ = true; + auto serialized_counter = G()->td_db()->get_binlog_pmc()->get("dlds_counter"); if (!serialized_counter.empty()) { log_event_parse(sent_counters_, serialized_counter).ensure(); @@ -361,7 +368,8 @@ class DownloadManagerImpl final : public DownloadManager { max_download_id_ = max(in_db.download_id, max_download_id_); add_file_from_db(in_db); } - is_synchonized_ = true; + + is_started_ = true; update_counters(); } @@ -390,32 +398,32 @@ class DownloadManagerImpl final : public DownloadManager { void prepare_hints() { for (auto &it : files_) { const auto &file_info = *it.second; - send_closure(G()->file_reference_manager(), &FileReferenceManager::get_file_search_info, file_info.file_source_id, + send_closure(G()->file_reference_manager(), &FileReferenceManager::get_file_search_text, file_info.file_source_id, callback_->get_file_view(file_info.file_id).get_unique_file_id(), - [self = actor_id(this), cont = mpas_.get_promise(), - download_id = it.first](Result result) mutable { - send_closure(self, &DownloadManagerImpl::add_download_to_hints, download_id, std::move(result), - std::move(cont)); + [self = actor_id(this), promise = load_search_text_multipromise_.get_promise(), + download_id = it.first](Result r_search_text) mutable { + send_closure(self, &DownloadManagerImpl::add_download_to_hints, download_id, + std::move(r_search_text), std::move(promise)); }); } } - void add_download_to_hints(int64 download_id, Result r_file_search_info, Promise promise) { + void add_download_to_hints(int64 download_id, Result r_search_text, Promise promise) { auto it = files_.find(download_id); if (it == files_.end()) { - return; + return promise.set_value(Unit()); } - if (r_file_search_info.is_error()) { + if (r_search_text.is_error()) { if (!G()->close_flag()) { remove_file(it->second->file_id, {}, false); } - return; + } else { + auto search_text = r_search_text.move_as_ok(); + // TODO: This is a race. Synchronous call to MessagesManager would be better. + hints_.add(download_id, search_text.empty() ? string(" ") : search_text); } - - auto search_info = r_file_search_info.move_as_ok(); - // TODO: This is a race. Synchronous call to MessagesManager would be better. - hints_.add(download_id, search_info.search_text.empty() ? string(" ") : search_info.search_text); + promise.set_value(Unit()); } void add_file_info(unique_ptr &&file_info, const string &search_text) { @@ -471,7 +479,7 @@ class DownloadManagerImpl final : public DownloadManager { } void update_counters() { - if (!is_synchonized_) { + if (!is_started_) { return; } if (counters_ == sent_counters_) { @@ -541,6 +549,7 @@ class DownloadManagerImpl final : public DownloadManager { LOG(ERROR) << "DownloadManager wasn't initialized"; return Status::Error(500, "DownloadManager isn't initialized"); } + CHECK(is_started_); return Status::OK(); } }; diff --git a/td/telegram/DownloadManager.h b/td/telegram/DownloadManager.h index 647d44182..5cb84970f 100644 --- a/td/telegram/DownloadManager.h +++ b/td/telegram/DownloadManager.h @@ -43,7 +43,7 @@ class DownloadManager : public Actor { void parse(ParserT &parser); }; - // trying to make DownloadManager testable, so all interactions with G() will be hidden is this probably monstrous interface + // to make DownloadManager testable all interactions with G() must be hidden in this probably monstrous interface class Callback { public: virtual ~Callback() = default; diff --git a/td/telegram/FileReferenceManager.cpp b/td/telegram/FileReferenceManager.cpp index ef9dca7b7..0748c34ca 100644 --- a/td/telegram/FileReferenceManager.cpp +++ b/td/telegram/FileReferenceManager.cpp @@ -394,13 +394,13 @@ void FileReferenceManager::reload_photo(PhotoSizeSource source, Promise pr } } -void FileReferenceManager::get_file_search_info(FileSourceId file_source_id, string unique_file_id, - Promise promise) { +void FileReferenceManager::get_file_search_text(FileSourceId file_source_id, string unique_file_id, + Promise promise) { auto index = static_cast(file_source_id.get()) - 1; CHECK(index < file_sources_.size()); file_sources_[index].visit(overloaded( [&](const FileSourceMessage &source) { - send_closure_later(G()->messages_manager(), &MessagesManager::get_message_file_search_info, + send_closure_later(G()->messages_manager(), &MessagesManager::get_message_file_search_text, source.full_message_id, std::move(unique_file_id), std::move(promise)); }, [&](const auto &source) { promise.set_error(Status::Error(500, "Unsupported file source")); })); diff --git a/td/telegram/FileReferenceManager.h b/td/telegram/FileReferenceManager.h index adc2a1344..1b581dc4c 100644 --- a/td/telegram/FileReferenceManager.h +++ b/td/telegram/FileReferenceManager.h @@ -33,11 +33,6 @@ class Td; extern int VERBOSITY_NAME(file_references); -struct FileSearchInfo { - FileId file_id; - string search_text; -}; - class FileReferenceManager final : public Actor { public: static bool is_file_reference_error(const Status &error); @@ -61,7 +56,7 @@ class FileReferenceManager final : public Actor { using NodeId = FileId; void repair_file_reference(NodeId node_id, Promise<> promise); - void get_file_search_info(FileSourceId file_source_id, string unique_file_id, Promise promise); + void get_file_search_text(FileSourceId file_source_id, string unique_file_id, Promise promise); td_api::object_ptr get_message_object(FileSourceId file_source_id) const; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index d4ca5f3d4..d2687a997 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -39882,9 +39882,9 @@ void MessagesManager::add_message_file_to_downloads(FullMessageId full_message_i promise.set_value(td_->file_manager_->get_file_object(file_id)); } -void MessagesManager::get_message_file_search_info(FullMessageId full_message_id, string unique_file_id, - Promise promise) { - auto m = get_message_force(full_message_id, "add_message_file_to_downloads"); +void MessagesManager::get_message_file_search_text(FullMessageId full_message_id, string unique_file_id, + Promise promise) { + auto m = get_message_force(full_message_id, "get_message_file_search_text"); if (m == nullptr) { return promise.set_error(Status::Error(200, "Message not found")); } @@ -39892,10 +39892,7 @@ void MessagesManager::get_message_file_search_info(FullMessageId full_message_id auto file_view = td_->file_manager_->get_file_view(file_id); CHECK(!file_view.empty()); if (file_view.get_unique_file_id() == unique_file_id) { - FileSearchInfo info; - info.file_id = file_id; - info.search_text = get_message_search_text(m); - return promise.set_value(std::move(info)); + return promise.set_value(get_message_search_text(m)); } } return promise.set_error(Status::Error(200, "File not found")); diff --git a/td/telegram/MessagesManager.h b/td/telegram/MessagesManager.h index ef4475599..693a68bfb 100644 --- a/td/telegram/MessagesManager.h +++ b/td/telegram/MessagesManager.h @@ -90,7 +90,6 @@ struct Dependencies; class DialogActionBar; class DialogFilter; class DraftMessage; -struct FileSearchInfo; struct InputMessageContent; class MessageContent; struct MessageReactions; @@ -984,8 +983,7 @@ class MessagesManager final : public Actor { void add_message_file_to_downloads(FullMessageId full_message_id, FileId file_id, int32 priority, Promise> promise); - void get_message_file_search_info(FullMessageId full_message_id, string unique_file_id, - Promise promise); + void get_message_file_search_text(FullMessageId full_message_id, string unique_file_id, Promise promise); private: class PendingPtsUpdate {