Improve DownloadManager initialization.

This commit is contained in:
levlam 2022-03-01 23:09:40 +03:00
parent 119999e684
commit 4d7afaedbb
6 changed files with 48 additions and 49 deletions

View File

@ -160,30 +160,38 @@ class DownloadManagerImpl final : public DownloadManager {
} }
void hints_synchronized(Result<Unit>) { void hints_synchronized(Result<Unit>) {
if (G()->close_flag()) {
return;
}
LOG(INFO) << "DownloadManager: hints are synchronized"; 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, void search(string query, bool only_active, bool only_completed, string offset, int32 limit,
Promise<td_api::object_ptr<td_api::foundFileDownloads>> promise) final { Promise<td_api::object_ptr<td_api::foundFileDownloads>> promise) final {
return do_search(std::move(query), only_active, only_completed, std::move(offset), limit, std::move(promise), return do_search(std::move(query), only_active, only_completed, std::move(offset), limit, std::move(promise),
Unit{}); Unit{});
} }
void do_search(string query, bool only_active, bool only_completed, string offset, int32 limit, void do_search(string query, bool only_active, bool only_completed, string offset, int32 limit,
Promise<td_api::object_ptr<td_api::foundFileDownloads>> promise, Result<Unit>) { Promise<td_api::object_ptr<td_api::foundFileDownloads>> promise, Result<Unit>) {
TRY_STATUS_PROMISE(promise, G()->close_status());
TRY_STATUS_PROMISE(promise, check_is_active()); TRY_STATUS_PROMISE(promise, check_is_active());
if (hints_state_ < 2) { if (!is_search_inited_) {
Promise<Unit> lock; Promise<Unit> lock;
if (hints_state_ == 0) { if (load_search_text_multipromise_.promise_count() == 0) {
mpas_.add_promise(promise_send_closure(actor_id(this), &DownloadManagerImpl::hints_synchronized)); load_search_text_multipromise_.add_promise(
mpas_.set_ignore_errors(true); promise_send_closure(actor_id(this), &DownloadManagerImpl::hints_synchronized));
lock = mpas_.get_promise(); load_search_text_multipromise_.set_ignore_errors(true);
lock = load_search_text_multipromise_.get_promise();
prepare_hints(); prepare_hints();
hints_state_ = 1;
} }
mpas_.add_promise(promise_send_closure(actor_id(this), &DownloadManagerImpl::do_search, std::move(query), load_search_text_multipromise_.add_promise(promise_send_closure(actor_id(this), &DownloadManagerImpl::do_search,
only_active, only_completed, std::move(offset), limit, std::move(query), only_active, only_completed,
std::move(promise))); std::move(offset), limit, std::move(promise)));
lock.set_value(Unit());
return; return;
} }
@ -300,12 +308,11 @@ class DownloadManagerImpl final : public DownloadManager {
Counters counters_; Counters counters_;
Counters sent_counters_; Counters sent_counters_;
bool is_synchonized_{false};
bool is_started_{false}; bool is_started_{false};
bool is_search_inited_{false};
int64 max_download_id_{0}; int64 max_download_id_{0};
uint64 last_link_token_{0}; uint64 last_link_token_{0};
int hints_state_; MultiPromiseActor load_search_text_multipromise_{"LoadFileSearchTextMultiPromiseActor"};
MultiPromiseActorSafe mpas_{"DownloadManager: hints"};
int64 next_download_id() { int64 next_download_id() {
return ++max_download_id_; return ++max_download_id_;
@ -344,7 +351,7 @@ class DownloadManagerImpl final : public DownloadManager {
if (is_started_) { if (is_started_) {
return; return;
} }
is_started_ = true;
auto serialized_counter = G()->td_db()->get_binlog_pmc()->get("dlds_counter"); auto serialized_counter = G()->td_db()->get_binlog_pmc()->get("dlds_counter");
if (!serialized_counter.empty()) { if (!serialized_counter.empty()) {
log_event_parse(sent_counters_, serialized_counter).ensure(); 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_); max_download_id_ = max(in_db.download_id, max_download_id_);
add_file_from_db(in_db); add_file_from_db(in_db);
} }
is_synchonized_ = true;
is_started_ = true;
update_counters(); update_counters();
} }
@ -390,32 +398,32 @@ class DownloadManagerImpl final : public DownloadManager {
void prepare_hints() { void prepare_hints() {
for (auto &it : files_) { for (auto &it : files_) {
const auto &file_info = *it.second; 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(), callback_->get_file_view(file_info.file_id).get_unique_file_id(),
[self = actor_id(this), cont = mpas_.get_promise(), [self = actor_id(this), promise = load_search_text_multipromise_.get_promise(),
download_id = it.first](Result<FileSearchInfo> result) mutable { download_id = it.first](Result<string> r_search_text) mutable {
send_closure(self, &DownloadManagerImpl::add_download_to_hints, download_id, std::move(result), send_closure(self, &DownloadManagerImpl::add_download_to_hints, download_id,
std::move(cont)); std::move(r_search_text), std::move(promise));
}); });
} }
} }
void add_download_to_hints(int64 download_id, Result<FileSearchInfo> r_file_search_info, Promise<Unit> promise) { void add_download_to_hints(int64 download_id, Result<string> r_search_text, Promise<Unit> promise) {
auto it = files_.find(download_id); auto it = files_.find(download_id);
if (it == files_.end()) { 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()) { if (!G()->close_flag()) {
remove_file(it->second->file_id, {}, false); 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);
} }
promise.set_value(Unit());
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);
} }
void add_file_info(unique_ptr<FileInfo> &&file_info, const string &search_text) { void add_file_info(unique_ptr<FileInfo> &&file_info, const string &search_text) {
@ -471,7 +479,7 @@ class DownloadManagerImpl final : public DownloadManager {
} }
void update_counters() { void update_counters() {
if (!is_synchonized_) { if (!is_started_) {
return; return;
} }
if (counters_ == sent_counters_) { if (counters_ == sent_counters_) {
@ -541,6 +549,7 @@ class DownloadManagerImpl final : public DownloadManager {
LOG(ERROR) << "DownloadManager wasn't initialized"; LOG(ERROR) << "DownloadManager wasn't initialized";
return Status::Error(500, "DownloadManager isn't initialized"); return Status::Error(500, "DownloadManager isn't initialized");
} }
CHECK(is_started_);
return Status::OK(); return Status::OK();
} }
}; };

View File

@ -43,7 +43,7 @@ class DownloadManager : public Actor {
void parse(ParserT &parser); 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 { class Callback {
public: public:
virtual ~Callback() = default; virtual ~Callback() = default;

View File

@ -394,13 +394,13 @@ void FileReferenceManager::reload_photo(PhotoSizeSource source, Promise<Unit> pr
} }
} }
void FileReferenceManager::get_file_search_info(FileSourceId file_source_id, string unique_file_id, void FileReferenceManager::get_file_search_text(FileSourceId file_source_id, string unique_file_id,
Promise<FileSearchInfo> promise) { Promise<string> promise) {
auto index = static_cast<size_t>(file_source_id.get()) - 1; auto index = static_cast<size_t>(file_source_id.get()) - 1;
CHECK(index < file_sources_.size()); CHECK(index < file_sources_.size());
file_sources_[index].visit(overloaded( file_sources_[index].visit(overloaded(
[&](const FileSourceMessage &source) { [&](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)); source.full_message_id, std::move(unique_file_id), std::move(promise));
}, },
[&](const auto &source) { promise.set_error(Status::Error(500, "Unsupported file source")); })); [&](const auto &source) { promise.set_error(Status::Error(500, "Unsupported file source")); }));

View File

@ -33,11 +33,6 @@ class Td;
extern int VERBOSITY_NAME(file_references); extern int VERBOSITY_NAME(file_references);
struct FileSearchInfo {
FileId file_id;
string search_text;
};
class FileReferenceManager final : public Actor { class FileReferenceManager final : public Actor {
public: public:
static bool is_file_reference_error(const Status &error); static bool is_file_reference_error(const Status &error);
@ -61,7 +56,7 @@ class FileReferenceManager final : public Actor {
using NodeId = FileId; using NodeId = FileId;
void repair_file_reference(NodeId node_id, Promise<> promise); void repair_file_reference(NodeId node_id, Promise<> promise);
void get_file_search_info(FileSourceId file_source_id, string unique_file_id, Promise<FileSearchInfo> promise); void get_file_search_text(FileSourceId file_source_id, string unique_file_id, Promise<string> promise);
td_api::object_ptr<td_api::message> get_message_object(FileSourceId file_source_id) const; td_api::object_ptr<td_api::message> get_message_object(FileSourceId file_source_id) const;

View File

@ -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)); 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, void MessagesManager::get_message_file_search_text(FullMessageId full_message_id, string unique_file_id,
Promise<FileSearchInfo> promise) { Promise<string> promise) {
auto m = get_message_force(full_message_id, "add_message_file_to_downloads"); auto m = get_message_force(full_message_id, "get_message_file_search_text");
if (m == nullptr) { if (m == nullptr) {
return promise.set_error(Status::Error(200, "Message not found")); 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); auto file_view = td_->file_manager_->get_file_view(file_id);
CHECK(!file_view.empty()); CHECK(!file_view.empty());
if (file_view.get_unique_file_id() == unique_file_id) { if (file_view.get_unique_file_id() == unique_file_id) {
FileSearchInfo info; return promise.set_value(get_message_search_text(m));
info.file_id = file_id;
info.search_text = get_message_search_text(m);
return promise.set_value(std::move(info));
} }
} }
return promise.set_error(Status::Error(200, "File not found")); return promise.set_error(Status::Error(200, "File not found"));

View File

@ -90,7 +90,6 @@ struct Dependencies;
class DialogActionBar; class DialogActionBar;
class DialogFilter; class DialogFilter;
class DraftMessage; class DraftMessage;
struct FileSearchInfo;
struct InputMessageContent; struct InputMessageContent;
class MessageContent; class MessageContent;
struct MessageReactions; 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, void add_message_file_to_downloads(FullMessageId full_message_id, FileId file_id, int32 priority,
Promise<td_api::object_ptr<td_api::file>> promise); Promise<td_api::object_ptr<td_api::file>> promise);
void get_message_file_search_info(FullMessageId full_message_id, string unique_file_id, void get_message_file_search_text(FullMessageId full_message_id, string unique_file_id, Promise<string> promise);
Promise<FileSearchInfo> promise);
private: private:
class PendingPtsUpdate { class PendingPtsUpdate {