FileManager: support limit={KEEP,IGNORE}_DOWNLOAD_LIMIT in download method

This commit is contained in:
Arseny Smirnov 2022-02-28 13:15:00 +01:00
parent 3e4128fc1d
commit 08675f2df1
4 changed files with 58 additions and 16 deletions

View File

@ -3981,11 +3981,12 @@ void Td::init_managers() {
send_closure(G()->td(), &Td::send_update, counters.get_update_file_downloads_object());
}
void start_file(FileId file_id, int8 priority) final {
send_closure(G()->file_manager(), &FileManager::download, file_id, make_download_file_callback(), priority, -1,
-1);
send_closure(G()->file_manager(), &FileManager::download, file_id, make_download_file_callback(), priority,
FileManager::KEEP_DOWNLOAD_OFFSET, FileManager::IGNORE_DOWNLOAD_LIMIT);
}
void pause_file(FileId file_id) final {
send_closure(G()->file_manager(), &FileManager::download, file_id, nullptr, 0, -1, -1);
send_closure(G()->file_manager(), &FileManager::download, file_id, nullptr, 0, FileManager::KEEP_DOWNLOAD_OFFSET,
FileManager::KEEP_DOWNLOAD_LIMIT);
}
void delete_file(FileId file_id) final {
send_closure(
@ -6506,7 +6507,8 @@ void Td::on_request(uint64 id, const td_api::getFileDownloadedPrefixSize &reques
}
void Td::on_request(uint64 id, const td_api::cancelDownloadFile &request) {
file_manager_->download(FileId(request.file_id_, 0), nullptr, request.only_if_pending_ ? -1 : 0, -1, -1);
file_manager_->download(FileId(request.file_id_, 0), nullptr, request.only_if_pending_ ? -1 : 0,
FileManager::KEEP_DOWNLOAD_OFFSET, FileManager::KEEP_DOWNLOAD_LIMIT);
send_closure(actor_id(this), &Td::send_result, id, make_tl_object<td_api::ok>());
}

View File

@ -83,10 +83,11 @@ class FileDownloadGenerateActor final : public FileGenerateActor {
};
send_closure(G()->file_manager(), &FileManager::download, file_id_, std::make_shared<Callback>(actor_id(this)), 1,
-1, -1);
FileManager::KEEP_DOWNLOAD_OFFSET, FileManager::KEEP_DOWNLOAD_LIMIT);
}
void hangup() final {
send_closure(G()->file_manager(), &FileManager::download, file_id_, nullptr, 0, -1, -1);
send_closure(G()->file_manager(), &FileManager::download, file_id_, nullptr, 0, FileManager::KEEP_DOWNLOAD_OFFSET,
FileManager::KEEP_DOWNLOAD_LIMIT);
stop();
}

View File

@ -180,6 +180,7 @@ void FileNode::init_ready_size() {
void FileNode::set_download_offset(int64 download_offset) {
if (download_offset < 0 || download_offset > MAX_FILE_SIZE) {
// KEEP_DOWNLOAD_OFFSET is handled here
return;
}
if (download_offset == download_offset_) {
@ -193,20 +194,44 @@ void FileNode::set_download_offset(int64 download_offset) {
recalc_ready_prefix_size(-1, -1);
on_info_changed();
}
void FileNode::set_download_limit(int64 download_limit) {
if (download_limit < 0) {
return;
int64 FileNode::get_download_limit() const {
if (ignore_download_limit_) {
return 0;
}
if (download_limit == download_limit_) {
return private_download_limit_;
}
void FileNode::update_effective_download_limit(int64 old_download_limit) {
if (get_download_limit() == old_download_limit) {
return;
}
VLOG(update_file) << "File " << main_file_id_ << " has changed download_limit from " << download_limit_ << " to "
<< download_limit;
download_limit_ = download_limit;
// Should be no false positives here
// When we use IGNORE_DOWNLOAD_LIMIT, set_download_limit will be ignored
// And in case we turn off ignore_download_limit, set_download_limit will not change effective downoad limit
VLOG(update_file) << "File " << main_file_id_ << " has changed download_limit from " << old_download_limit << " to "
<< get_download_limit() << " (limit=" << private_download_limit_
<< ";ignore=" << ignore_download_limit_ << ")";
is_download_limit_dirty_ = true;
}
void FileNode::set_download_limit(int64 download_limit) {
if (download_limit < 0) {
// KEEP_DOWNLOAD_LIMIT is handled here
return;
}
auto old_download_limit = get_download_limit();
private_download_limit_ = download_limit;
update_effective_download_limit(old_download_limit);
}
void FileNode::set_ignore_download_limit(bool ignore_download_limit) {
auto old_download_limit = get_download_limit();
ignore_download_limit_ = ignore_download_limit;
update_effective_download_limit(old_download_limit);
}
void FileNode::drop_local_location() {
set_local_location(LocalFileLocation(), 0, -1, -1);
}
@ -2203,6 +2228,7 @@ void FileManager::download(FileId file_id, std::shared_ptr<DownloadCallback> cal
CHECK(new_priority == 0);
file_info->download_callback_->on_download_error(file_id, Status::Error(200, "Canceled"));
}
file_info->ignore_download_limit = limit == IGNORE_DOWNLOAD_LIMIT;
file_info->download_priority_ = narrow_cast<int8>(new_priority);
file_info->download_callback_ = std::move(callback);
@ -2219,11 +2245,13 @@ void FileManager::download(FileId file_id, std::shared_ptr<DownloadCallback> cal
void FileManager::run_download(FileNodePtr node, bool force_update_priority) {
int8 priority = 0;
bool ignore_download_limit = false;
for (auto id : node->file_ids_) {
auto *info = get_file_id_info(id);
if (info->download_priority_ > priority) {
priority = info->download_priority_;
}
ignore_download_limit |= info->ignore_download_limit;
}
auto old_priority = node->download_priority_;
@ -2251,6 +2279,7 @@ void FileManager::run_download(FileNodePtr node, bool force_update_priority) {
return;
}
node->set_download_priority(priority);
node->set_ignore_download_limit(ignore_download_limit);
bool need_update_offset = node->is_download_offset_dirty_;
node->is_download_offset_dirty_ = false;
@ -2265,7 +2294,7 @@ void FileManager::run_download(FileNodePtr node, bool force_update_priority) {
}
if (need_update_limit || need_update_offset) {
auto download_offset = node->download_offset_;
auto download_limit = node->download_limit_;
auto download_limit = node->get_download_limit();
if (file_view.is_encrypted_any()) {
CHECK(download_offset <= MAX_FILE_SIZE);
CHECK(download_limit <= std::numeric_limits<int32>::max());
@ -2334,7 +2363,7 @@ void FileManager::run_download(FileNodePtr node, bool force_update_priority) {
<< node->remote_.full.value() << " with suggested name " << node->suggested_path() << " and encyption key "
<< node->encryption_key_;
auto download_offset = node->download_offset_;
auto download_limit = node->download_limit_;
auto download_limit = node->get_download_limit();
if (file_view.is_encrypted_any()) {
CHECK(download_offset <= MAX_FILE_SIZE);
CHECK(download_limit <= std::numeric_limits<int32>::max());

View File

@ -105,6 +105,7 @@ class FileNode {
void set_download_offset(int64 download_offset);
void set_download_limit(int64 download_limit);
void set_ignore_download_limit(bool ignore_download_limit);
void on_changed();
void on_info_changed();
@ -116,6 +117,8 @@ class FileNode {
void on_pmc_flushed();
void on_info_flushed();
int64 get_download_limit() const;
string suggested_path() const;
private:
@ -129,7 +132,7 @@ class FileNode {
LocalFileLocation local_;
FileLoadManager::QueryId upload_id_ = 0;
int64 download_offset_ = 0;
int64 download_limit_ = 0;
int64 private_download_limit_ = 0;
int64 local_ready_size_ = 0; // PartialLocal only
int64 local_ready_prefix_size_ = 0; // PartialLocal only
@ -184,9 +187,12 @@ class FileNode {
bool upload_prefer_small_{false};
bool ignore_download_limit_{false};
void init_ready_size();
void recalc_ready_prefix_size(int64 prefix_offset, int64 ready_prefix_size);
void update_effective_download_limit(int64 old_download_limit);
};
class FileManager;
@ -342,6 +348,9 @@ class FileView {
class FileManager final : public FileLoadManager::Callback {
public:
static constexpr int64 KEEP_DOWNLOAD_LIMIT = -1;
static constexpr int64 KEEP_DOWNLOAD_OFFSET = -1;
static constexpr int64 IGNORE_DOWNLOAD_LIMIT = -2;
class DownloadCallback {
public:
DownloadCallback() = default;
@ -534,6 +543,7 @@ class FileManager final : public FileLoadManager::Callback {
bool send_updates_flag_{false};
bool pin_flag_{false};
bool sent_file_id_flag_{false};
bool ignore_download_limit{false};
int8 download_priority_{0};
int8 upload_priority_{0};