Reset updateFileDownloads after all downloaded messages are viewed.

This commit is contained in:
levlam 2022-03-03 13:44:05 +03:00
parent 1b8a506312
commit fdd218de4a
4 changed files with 62 additions and 14 deletions

View File

@ -98,6 +98,7 @@ class DownloadManagerImpl final : public DownloadManager {
TRY_STATUS(check_is_active()); TRY_STATUS(check_is_active());
TRY_RESULT(file_info_ptr, get_file_info(file_id, file_source_id)); TRY_RESULT(file_info_ptr, get_file_info(file_id, file_source_id));
auto &file_info = *file_info_ptr; auto &file_info = *file_info_ptr;
auto download_id = file_info.download_id;
if (!file_info.is_paused) { if (!file_info.is_paused) {
callback_->pause_file(file_info.internal_file_id); callback_->pause_file(file_info.internal_file_id);
} }
@ -107,12 +108,15 @@ class DownloadManagerImpl final : public DownloadManager {
} }
by_internal_file_id_.erase(file_info.internal_file_id); by_internal_file_id_.erase(file_info.internal_file_id);
by_file_id_.erase(file_info.file_id); by_file_id_.erase(file_info.file_id);
hints_.remove(file_info.download_id); hints_.remove(download_id);
completed_download_ids_.erase(file_info.download_id); completed_download_ids_.erase(download_id);
remove_from_db(file_info); remove_from_db(file_info);
files_.erase(file_info.download_id); files_.erase(download_id);
callback_->update_file_removed(file_id); callback_->update_file_removed(file_id);
on_file_viewed(download_id);
return Status::OK(); return Status::OK();
} }
@ -175,7 +179,6 @@ class DownloadManagerImpl final : public DownloadManager {
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 {
clear_counters();
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{});
} }
@ -212,9 +215,9 @@ class DownloadManagerImpl final : public DownloadManager {
} }
offset_int64 = r_offset.move_as_ok(); offset_int64 = r_offset.move_as_ok();
} }
auto ids = hints_.search(query, 10000, true).second; auto download_ids = hints_.search(query, 10000, true).second;
int32 total_count = 0; int32 total_count = 0;
td::remove_if(ids, [&](auto download_id) { td::remove_if(download_ids, [&](int64 download_id) {
auto r = get_file_info(download_id); auto r = get_file_info(download_id);
CHECK(r.is_ok()); CHECK(r.is_ok());
auto &file_info = *r.ok(); auto &file_info = *r.ok();
@ -230,12 +233,14 @@ class DownloadManagerImpl final : public DownloadManager {
} }
return false; return false;
}); });
std::sort(ids.begin(), ids.end(), std::greater<>()); std::sort(download_ids.begin(), download_ids.end(), std::greater<>());
if (total_count > limit) { if (total_count > limit) {
ids.resize(limit); download_ids.resize(limit);
} }
auto file_downloads = transform(ids, [&](auto id) { auto file_downloads = transform(download_ids, [&](int64 download_id) {
auto it = files_.find(id); on_file_viewed(download_id);
auto it = files_.find(download_id);
CHECK(it != files_.end()); CHECK(it != files_.end());
const FileInfo &file_info = *it->second; const FileInfo &file_info = *it->second;
return callback_->get_file_download_object(file_info.file_id, file_info.file_source_id, file_info.created_at, return callback_->get_file_download_object(file_info.file_id, file_info.file_source_id, file_info.created_at,
@ -243,8 +248,8 @@ class DownloadManagerImpl final : public DownloadManager {
}); });
td::remove_if(file_downloads, [](const auto &file_download) { return file_download->message_ == nullptr; }); td::remove_if(file_downloads, [](const auto &file_download) { return file_download->message_ == nullptr; });
string next_offset; string next_offset;
if (!ids.empty()) { if (!download_ids.empty()) {
next_offset = to_string(ids.back()); next_offset = to_string(download_ids.back());
} }
promise.set_value( promise.set_value(
td_api::make_object<td_api::foundFileDownloads>(total_count, std::move(file_downloads), next_offset)); td_api::make_object<td_api::foundFileDownloads>(total_count, std::move(file_downloads), next_offset));
@ -291,6 +296,19 @@ class DownloadManagerImpl final : public DownloadManager {
remove_file(file_info.file_id, {}, false); remove_file(file_info.file_id, {}, false);
} }
void update_file_viewed(FileId file_id, FileSourceId file_source_id) final {
if (unviewed_completed_download_ids_.empty() || !callback_) {
return;
}
auto r_file_info_ptr = get_file_info(file_id, file_source_id);
if (r_file_info_ptr.is_error()) {
return;
}
auto &file_info = *r_file_info_ptr.ok();
on_file_viewed(file_info.download_id);
}
private: private:
unique_ptr<Callback> callback_; unique_ptr<Callback> callback_;
struct FileInfo { struct FileInfo {
@ -314,6 +332,7 @@ class DownloadManagerImpl final : public DownloadManager {
FlatHashMap<FileId, int64, FileIdHash> by_internal_file_id_; FlatHashMap<FileId, int64, FileIdHash> by_internal_file_id_;
FlatHashMap<int64, unique_ptr<FileInfo>> files_; FlatHashMap<int64, unique_ptr<FileInfo>> files_;
std::set<int64> completed_download_ids_; std::set<int64> completed_download_ids_;
FlatHashSet<int64> unviewed_completed_download_ids_;
Hints hints_; Hints hints_;
Counters counters_; Counters counters_;
@ -529,7 +548,7 @@ class DownloadManagerImpl final : public DownloadManager {
} }
LOG(INFO) << "Change is_paused state of file " << file_info.file_id << " to " << is_paused; LOG(INFO) << "Change is_paused state of file " << file_info.file_id << " to " << is_paused;
with_file_info(file_info, [&](auto &file_info) { with_file_info(file_info, [&](FileInfo &file_info) {
file_info.is_paused = is_paused; file_info.is_paused = is_paused;
file_info.need_save_to_db = true; file_info.need_save_to_db = true;
file_info.link_token = ++last_link_token_; file_info.link_token = ++last_link_token_;
@ -555,9 +574,12 @@ class DownloadManagerImpl final : public DownloadManager {
if (counters_.total_size != 0) { if (counters_.total_size != 0) {
constexpr double EMPTY_UPDATE_DELAY = 60.0; constexpr double EMPTY_UPDATE_DELAY = 60.0;
set_timeout_in(EMPTY_UPDATE_DELAY); set_timeout_in(EMPTY_UPDATE_DELAY);
} else {
cancel_timeout();
} }
G()->td_db()->get_binlog_pmc()->erase("dlds_counter"); G()->td_db()->get_binlog_pmc()->erase("dlds_counter");
} else { } else {
cancel_timeout();
G()->td_db()->get_binlog_pmc()->set("dlds_counter", log_event_store(counters_).as_slice().str()); G()->td_db()->get_binlog_pmc()->set("dlds_counter", log_event_store(counters_).as_slice().str());
} }
sent_counters_ = counters_; sent_counters_ = counters_;
@ -609,6 +631,9 @@ class DownloadManagerImpl final : public DownloadManager {
bool is_inserted = completed_download_ids_.insert(file_info.download_id).second; bool is_inserted = completed_download_ids_.insert(file_info.download_id).second;
CHECK(is_inserted); CHECK(is_inserted);
if (file_info.is_counted) {
unviewed_completed_download_ids_.insert(file_info.download_id);
}
} }
if (file_info.is_counted && !file_info.is_paused) { if (file_info.is_counted && !file_info.is_paused) {
counters_.downloaded_size += file_info.downloaded_size; counters_.downloaded_size += file_info.downloaded_size;
@ -630,6 +655,17 @@ class DownloadManagerImpl final : public DownloadManager {
} }
} }
void on_file_viewed(int64 download_id) {
if (unviewed_completed_download_ids_.empty()) {
return;
}
unviewed_completed_download_ids_.erase(download_id);
if (unviewed_completed_download_ids_.empty()) {
clear_counters();
}
}
template <class F> template <class F>
void with_file_info(const FileInfo &const_file_info, F &&f) { void with_file_info(const FileInfo &const_file_info, F &&f) {
unregister_file_info(const_file_info); unregister_file_info(const_file_info);

View File

@ -78,6 +78,7 @@ class DownloadManager : public Actor {
virtual void update_file_download_state(FileId internal_file_id, int64 downloaded_size, int64 size, virtual void update_file_download_state(FileId internal_file_id, int64 downloaded_size, int64 size,
int64 expected_size, bool is_paused) = 0; int64 expected_size, bool is_paused) = 0;
virtual void update_file_deleted(FileId internal_file_id) = 0; virtual void update_file_deleted(FileId internal_file_id) = 0;
virtual void update_file_viewed(FileId file_id, FileSourceId file_source_id) = 0;
}; };
} // namespace td } // namespace td

View File

@ -20639,6 +20639,17 @@ Status MessagesManager::view_messages(DialogId dialog_id, MessageId top_thread_m
read_content_message_ids.push_back(m->message_id); read_content_message_ids.push_back(m->message_id);
on_message_changed(d, m, true, "view_messages"); on_message_changed(d, m, true, "view_messages");
} }
auto it = full_message_id_to_file_source_id_.find({dialog_id, m->message_id});
if (it != full_message_id_to_file_source_id_.end()) {
auto file_source_id = it->second;
CHECK(file_source_id.is_valid());
for (auto file_id : get_message_file_ids(m)) {
auto file_view = td_->file_manager_->get_file_view(file_id);
CHECK(!file_view.empty());
td_->download_manager_->update_file_viewed(file_view.file_id(), file_source_id);
}
}
} else if (!message_id.is_yet_unsent() && message_id > max_message_id && } else if (!message_id.is_yet_unsent() && message_id > max_message_id &&
message_id <= d->max_notification_message_id) { message_id <= d->max_notification_message_id) {
max_message_id = message_id; max_message_id = message_id;

View File

@ -122,7 +122,7 @@ void FileLoader::start_up() {
// location untouched. This is completely possible at this point, but probably should be fixed. // location untouched. This is completely possible at this point, but probably should be fixed.
auto status = auto status =
parts_manager_.init(size, expected_size, is_size_final, part_size, ready_parts, use_part_count_limit, is_upload); parts_manager_.init(size, expected_size, is_size_final, part_size, ready_parts, use_part_count_limit, is_upload);
LOG(DEBUG) << "Start " << (is_upload ? "up" : "down") << "load of a file of size " << size << " with expected " LOG(DEBUG) << "Start " << (is_upload ? "up" : "down") << "loading a file of size " << size << " with expected "
<< (is_size_final ? "exact" : "approximate") << " size " << expected_size << ", part size " << part_size << (is_size_final ? "exact" : "approximate") << " size " << expected_size << ", part size " << part_size
<< " and " << ready_parts.size() << " ready parts: " << status; << " and " << ready_parts.size() << " ready parts: " << status;
if (status.is_error()) { if (status.is_error()) {