File reference improvements.

GitOrigin-RevId: 40d3ac6cde73503af544df464cc9ff569fb4016d
This commit is contained in:
levlam 2019-01-05 18:13:27 +03:00
parent cc5eaa6b7e
commit f54a0c3e70
4 changed files with 35 additions and 27 deletions

View File

@ -6,6 +6,7 @@
//
#include "td/telegram/FileReferenceManager.h"
#include "td/telegram/files/FileManager.h"
#include "td/telegram/Global.h"
#include "td/telegram/MessagesManager.h"
@ -31,9 +32,6 @@ void FileReferenceManager::update_file_reference(FileId file_id, std::vector<Fil
MultiPromiseActorSafe mpas{"UpdateFileReferenceMultiPromiseActor"};
mpas.add_promise(std::move(promise));
auto lock = mpas.get_promise();
SCOPE_EXIT {
lock.set_value(Unit());
};
for (auto source_id : sources) {
auto it = to_full_message_id_.find(source_id);
auto new_promise = PromiseCreator::lambda([promise = mpas.get_promise(), file_id, source_id,
@ -47,7 +45,7 @@ void FileReferenceManager::update_file_reference(FileId file_id, std::vector<Fil
promise.set_value(Unit());
});
if (it == to_full_message_id_.end()) {
new_promise.set_error(Status::Error("Unkonwn source id"));
new_promise.set_error(Status::Error("Unknown source id"));
continue;
}
@ -56,6 +54,7 @@ void FileReferenceManager::update_file_reference(FileId file_id, std::vector<Fil
send_closure_later(G()->messages_manager(), &MessagesManager::get_messages_from_server, std::move(message_ids),
std::move(new_promise), nullptr);
}
lock.set_value(Unit());
}
} // namespace td

View File

@ -271,7 +271,7 @@ Result<std::pair<NetQueryPtr, bool>> FileDownloader::start_part(Part part, int32
Status FileDownloader::check_net_query(NetQueryPtr &net_query) {
if (net_query->is_error()) {
auto error = net_query->move_as_error();
if (begins_with(error.message(), "FILE_REFERENCE_")) {
if (error.code() == 400 && begins_with(error.message(), "FILE_REFERENCE_")) {
error = Status::Error(400, PSLICE()
<< "FILE_REFERENCE_EXPIRED_BASE64" << base64_encode(remote_.get_file_reference()));
}

View File

@ -553,7 +553,7 @@ class FullRemoteFileLocation {
bool has_file_reference() const {
return !file_reference_.empty();
}
string get_file_reference() const {
const string &get_file_reference() const {
return file_reference_;
}
string get_url() const {

View File

@ -352,13 +352,16 @@ string FileNode::suggested_name() const {
bool FileView::has_local_location() const {
return node_->local_.type() == LocalFileLocation::Type::Full;
}
const FullLocalFileLocation &FileView::local_location() const {
CHECK(has_local_location());
return node_->local_.full();
}
bool FileView::has_remote_location() const {
return node_->remote_.type() == RemoteFileLocation::Type::Full;
}
bool FileView::has_active_remote_location() const {
if (!has_remote_location()) {
return false;
@ -368,6 +371,7 @@ bool FileView::has_active_remote_location() const {
}
return remote_location().has_file_reference();
}
const FullRemoteFileLocation &FileView::remote_location() const {
CHECK(has_remote_location());
auto *remote = node_.get_remote();
@ -376,9 +380,11 @@ const FullRemoteFileLocation &FileView::remote_location() const {
}
return node_->remote_.full();
}
bool FileView::has_generate_location() const {
return node_->generate_ != nullptr;
}
const FullGenerateFileLocation &FileView::generate_location() const {
CHECK(has_generate_location());
return *node_->generate_;
@ -989,12 +995,14 @@ static int merge_choose_remote_location(const RemoteFileLocation &x, int8 x_sour
return x.full().is_web(); // prefer non-web
}
auto x_ref = x.full().has_file_reference();
auto y_ref = !y.full().has_file_reference();
auto y_ref = y.full().has_file_reference();
if (x_ref || y_ref) {
if (x_ref != y_ref) {
return !x_ref;
}
return x_source < y_source;
if (x.full().get_file_reference() != y.full().get_file_reference()) {
return x_source < y_source;
}
}
if (x.full().get_access_hash() != y.full().get_access_hash()) {
return x_source < y_source;
@ -1356,7 +1364,7 @@ void FileManager::add_file_source(FileId file_id, FileSourceId file_source_id) {
}
void FileManager::remove_file_source(FileId file_id, FileSourceId file_source_id) {
LOG(ERROR) << "Remove file source " << file_id, file_source_id;
LOG(ERROR) << "Remove file source " << file_id << " " << file_source_id;
auto node = get_file_node(file_id);
if (!node) {
return;
@ -1752,7 +1760,7 @@ void FileManager::run_download(FileNodePtr node) {
// If file reference is needed
if (!file_view.has_active_remote_location()) {
LOG(INFO) << "run_download: Do not have valid file_reference " << file_id;
LOG(INFO) << "run_download: Do not have valid file_reference for file " << file_id;
QueryId id = queries_container_.create(Query{file_id, Query::DownloadWaitFileReferece});
node->download_id_ = id;
if (node->file_source_ids_.empty()) {
@ -1760,23 +1768,23 @@ void FileManager::run_download(FileNodePtr node) {
return;
}
if (!node->download_may_update_file_reference_) {
on_error(id, Status::Error("Can't download file: have valid source id, but do not allowed to use id"));
on_error(id, Status::Error("Can't download file: have valid source id, but do not allowed to use it"));
return;
}
node->download_may_update_file_reference_ = false;
send_closure(
G()->file_reference_manager(), &FileReferenceManager::update_file_reference, file_id, node->file_source_ids_,
PromiseCreator::lambda([id, actor_id = actor_id(this), file_id](Result<Unit> res) {
Status error;
if (res.is_ok()) {
error = td::Status::Error("FILE_DOWNLOAD_RESTART_WITH_FILE_REFERENCE");
} else {
error = res.move_as_error();
}
LOG(INFO) << "run_download: Got result from FileSourceManager for file " << file_id << " : " << error;
send_closure(actor_id, &FileManager::on_error, id, std::move(error));
}));
send_closure(G()->file_reference_manager(), &FileReferenceManager::update_file_reference, file_id,
node->file_source_ids_,
PromiseCreator::lambda([id, actor_id = actor_id(this), file_id](Result<Unit> res) {
Status error;
if (res.is_ok()) {
error = Status::Error("FILE_DOWNLOAD_RESTART_WITH_FILE_REFERENCE");
} else {
error = res.move_as_error();
}
LOG(INFO) << "run_download: Got result from FileSourceManager for file " << file_id << ": " << error;
send_closure(actor_id, &FileManager::on_error, id, std::move(error));
}));
return;
}
@ -2772,10 +2780,11 @@ void FileManager::on_error_impl(FileNodePtr node, FileManager::Query::Type type,
string file_reference;
Slice prefix = "FILE_REFERENCE_EXPIRED_BASE64";
if (begins_with(status.message(), prefix)) {
auto tmp = base64_decode(status.message().substr(prefix.size()));
LOG_IF(WARNING, tmp.is_error()) << "Can't decode file reference from error " << status << " " << tmp.error();
if (tmp.is_ok()) {
file_reference = tmp.move_as_ok();
auto r_file_reference = base64_decode(status.message().substr(prefix.size()));
if (r_file_reference.is_ok()) {
file_reference = r_file_reference.move_as_ok();
} else {
LOG(ERROR) << "Can't decode file reference from error " << status << ": " << r_file_reference.error();
}
} else {
LOG(ERROR) << "Unexpected error, file_reference will be deleted just in case " << status;