FileReference: better infinity loop protection
GitOrigin-RevId: 068fdbbb574eae03f3bb4b5b06ac3960aaca59c0
This commit is contained in:
parent
bbecdcda20
commit
b53cd5d76a
@ -37,7 +37,7 @@ void FileReferenceManager::update_file_reference(FileId file_id, std::vector<Fil
|
|||||||
for (auto source_id : sources) {
|
for (auto source_id : sources) {
|
||||||
auto it = to_full_message_id_.find(source_id);
|
auto it = to_full_message_id_.find(source_id);
|
||||||
auto new_promise = PromiseCreator::lambda([promise = mpas.get_promise(), file_id, source_id,
|
auto new_promise = PromiseCreator::lambda([promise = mpas.get_promise(), file_id, source_id,
|
||||||
file_manager = G()->file_manager()](Result<Unit> res) mutable {
|
file_manager = G()->file_manager()](Result<Unit> res) mutable {
|
||||||
if (res.is_error()) {
|
if (res.is_error()) {
|
||||||
LOG(INFO) << "Invalid source id " << source_id << " " << res.error();
|
LOG(INFO) << "Invalid source id " << source_id << " " << res.error();
|
||||||
send_closure(file_manager, &FileManager::remove_file_source, file_id, source_id);
|
send_closure(file_manager, &FileManager::remove_file_source, file_id, source_id);
|
||||||
|
@ -161,6 +161,8 @@ void FileNode::set_remote_location(const RemoteFileLocation &remote, FileLocatio
|
|||||||
|
|
||||||
void FileNode::delete_file_reference(Slice file_reference) {
|
void FileNode::delete_file_reference(Slice file_reference) {
|
||||||
if (remote_.type() == RemoteFileLocation::Type::Full && remote_.full().delete_file_reference(file_reference)) {
|
if (remote_.type() == RemoteFileLocation::Type::Full && remote_.full().delete_file_reference(file_reference)) {
|
||||||
|
upload_may_update_file_reference_ = true;
|
||||||
|
download_may_update_file_reference_ = true;
|
||||||
on_pmc_changed();
|
on_pmc_changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -257,6 +259,8 @@ void FileNode::add_file_source(FileSourceId file_source_id) {
|
|||||||
if (std::find(file_source_ids_.begin(), file_source_ids_.end(), file_source_id) != file_source_ids_.end()) {
|
if (std::find(file_source_ids_.begin(), file_source_ids_.end(), file_source_id) != file_source_ids_.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
upload_may_update_file_reference_ = true;
|
||||||
|
download_may_update_file_reference_ = true;
|
||||||
file_source_ids_.push_back(file_source_id);
|
file_source_ids_.push_back(file_source_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1080,6 +1084,7 @@ void FileManager::cancel_download(FileNodePtr node) {
|
|||||||
send_closure(file_load_manager_, &FileLoadManager::cancel, node->download_id_);
|
send_closure(file_load_manager_, &FileLoadManager::cancel, node->download_id_);
|
||||||
node->download_id_ = 0;
|
node->download_id_ = 0;
|
||||||
node->is_download_started_ = false;
|
node->is_download_started_ = false;
|
||||||
|
node->download_may_update_file_reference_ = !node->file_source_ids_.empty();
|
||||||
node->set_download_priority(0);
|
node->set_download_priority(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1089,6 +1094,7 @@ void FileManager::cancel_upload(FileNodePtr node) {
|
|||||||
}
|
}
|
||||||
send_closure(file_load_manager_, &FileLoadManager::cancel, node->upload_id_);
|
send_closure(file_load_manager_, &FileLoadManager::cancel, node->upload_id_);
|
||||||
node->upload_id_ = 0;
|
node->upload_id_ = 0;
|
||||||
|
node->upload_may_update_file_reference_ = !node->file_source_ids_.empty();
|
||||||
node->set_upload_priority(0);
|
node->set_upload_priority(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1746,12 +1752,17 @@ void FileManager::run_download(FileNodePtr node) {
|
|||||||
// If file reference is needed
|
// If file reference is needed
|
||||||
if (!file_view.has_active_remote_location()) {
|
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 " << file_id;
|
||||||
QueryId id = queries_container_.create(Query{file_id, Query::Download});
|
QueryId id = queries_container_.create(Query{file_id, Query::DownloadWaitFileReferece});
|
||||||
node->download_id_ = id;
|
node->download_id_ = id;
|
||||||
if (node->file_source_ids_.empty()) {
|
if (node->file_source_ids_.empty()) {
|
||||||
on_error(id, Status::Error("Can't download file: have valid file reference and no valid source id"));
|
on_error(id, Status::Error("Can't download file: have no valid file reference and no valid source id"));
|
||||||
return;
|
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"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
node->download_may_update_file_reference_ = false;
|
||||||
|
|
||||||
send_closure(
|
send_closure(
|
||||||
G()->file_reference_manager(), &FileReferenceManager::update_file_reference, file_id, node->file_source_ids_,
|
G()->file_reference_manager(), &FileReferenceManager::update_file_reference, file_id, node->file_source_ids_,
|
||||||
@ -2029,9 +2040,11 @@ void FileManager::run_upload(FileNodePtr node, std::vector<int> bad_parts) {
|
|||||||
CHECK(node->upload_id_ == 0);
|
CHECK(node->upload_id_ == 0);
|
||||||
if (file_view.has_remote_location() && !file_view.has_active_remote_location() &&
|
if (file_view.has_remote_location() && !file_view.has_active_remote_location() &&
|
||||||
file_view.get_type() != FileType::Thumbnail && file_view.get_type() != FileType::EncryptedThumbnail &&
|
file_view.get_type() != FileType::Thumbnail && file_view.get_type() != FileType::EncryptedThumbnail &&
|
||||||
!node->file_source_ids_.empty()) {
|
!node->file_source_ids_.empty() && node->upload_may_update_file_reference_) {
|
||||||
QueryId id = queries_container_.create(Query{file_id, Query::Upload});
|
QueryId id = queries_container_.create(Query{file_id, Query::UploadWaitFileReference});
|
||||||
node->upload_id_ = id;
|
node->upload_id_ = id;
|
||||||
|
node->upload_may_update_file_reference_ = false;
|
||||||
|
|
||||||
send_closure(G()->file_reference_manager(), &FileReferenceManager::update_file_reference, file_id,
|
send_closure(G()->file_reference_manager(), &FileReferenceManager::update_file_reference, file_id,
|
||||||
node->file_source_ids_, PromiseCreator::lambda([id, actor_id = actor_id(this)](Result<Unit> res) {
|
node->file_source_ids_, PromiseCreator::lambda([id, actor_id = actor_id(this)](Result<Unit> res) {
|
||||||
send_closure(actor_id, &FileManager::on_error, id, Status::Error("FILE_UPLOAD_RESTART"));
|
send_closure(actor_id, &FileManager::on_error, id, Status::Error("FILE_UPLOAD_RESTART"));
|
||||||
@ -2777,19 +2790,11 @@ void FileManager::on_error_impl(FileNodePtr node, FileManager::Query::Type type,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (begins_with(status.message(), "FILE_DOWNLOAD_RESTART")) {
|
if (begins_with(status.message(), "FILE_DOWNLOAD_RESTART")) {
|
||||||
if (ends_with(status.message(), "WITH_FILE_REFERENCE")) {
|
if (!ends_with(status.message(), "WITH_FILE_REFERENCE")) {
|
||||||
if (FileView(node).has_active_remote_location()) {
|
|
||||||
run_download(node);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LOG_IF(WARNING, !node->file_source_ids_.empty())
|
|
||||||
<< "Got no active remote locations, but have file_source_ids, download will be cancelled "
|
|
||||||
<< FileView(node).remote_location();
|
|
||||||
} else {
|
|
||||||
node->can_search_locally_ = false;
|
node->can_search_locally_ = false;
|
||||||
run_download(node);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
run_download(node);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!was_active) {
|
if (!was_active) {
|
||||||
|
@ -151,6 +151,9 @@ class FileNode {
|
|||||||
bool pmc_changed_flag_{false};
|
bool pmc_changed_flag_{false};
|
||||||
bool info_changed_flag_{false};
|
bool info_changed_flag_{false};
|
||||||
|
|
||||||
|
bool upload_may_update_file_reference_{false};
|
||||||
|
bool download_may_update_file_reference_{false};
|
||||||
|
|
||||||
void init_ready_size();
|
void init_ready_size();
|
||||||
|
|
||||||
void recalc_ready_prefix_size(int64 prefix_offset, int64 ready_prefix_size);
|
void recalc_ready_prefix_size(int64 prefix_offset, int64 ready_prefix_size);
|
||||||
@ -408,7 +411,15 @@ class FileManager : public FileLoadManager::Callback {
|
|||||||
class Query {
|
class Query {
|
||||||
public:
|
public:
|
||||||
FileId file_id_;
|
FileId file_id_;
|
||||||
enum Type : int32 { UploadByHash, Upload, Download, SetContent, Generate } type_;
|
enum Type : int32 {
|
||||||
|
UploadByHash,
|
||||||
|
UploadWaitFileReference,
|
||||||
|
Upload,
|
||||||
|
DownloadWaitFileReferece,
|
||||||
|
Download,
|
||||||
|
SetContent,
|
||||||
|
Generate
|
||||||
|
} type_;
|
||||||
};
|
};
|
||||||
struct FileIdInfo {
|
struct FileIdInfo {
|
||||||
FileNodeId node_id_{0};
|
FileNodeId node_id_{0};
|
||||||
|
Loading…
Reference in New Issue
Block a user