PartsManager: handle some errors

GitOrigin-RevId: c0f65cce76ece49ec99557503d79da66995e44c8
This commit is contained in:
Arseny Smirnov 2019-07-31 18:04:38 +03:00
parent 4d33451758
commit 1d570ca85c
6 changed files with 33 additions and 6 deletions

View File

@ -97,7 +97,9 @@ void FileLoader::start_up() {
auto part_size = file_info.part_size;
auto &ready_parts = file_info.ready_parts;
auto use_part_count_limit = file_info.use_part_count_limit;
auto status = parts_manager_.init(size, expected_size, is_size_final, part_size, ready_parts, use_part_count_limit);
bool is_upload = file_info.is_upload;
auto status =
parts_manager_.init(size, expected_size, is_size_final, part_size, ready_parts, use_part_count_limit, is_upload);
if (status.is_error()) {
on_error(std::move(status));
stop_flag_ = true;

View File

@ -61,6 +61,7 @@ class FileLoader : public FileLoaderActor {
bool need_delay = false;
int64 offset{0};
int64 limit{0};
bool is_upload{false};
};
virtual Result<FileInfo> init() TD_WARN_UNUSED_RESULT = 0;
virtual Status on_ok(int64 size) TD_WARN_UNUSED_RESULT = 0;

View File

@ -88,6 +88,7 @@ Result<FileLoader::FileInfo> FileUploader::init() {
res.is_size_final = local_is_ready_;
res.part_size = part_size;
res.ready_parts = std::move(parts);
res.is_upload = true;
return res;
}

View File

@ -96,8 +96,9 @@ Status PartsManager::init_no_size(size_t part_size, const std::vector<int> &read
}
Status PartsManager::init(int64 size, int64 expected_size, bool is_size_final, size_t part_size,
const std::vector<int> &ready_parts, bool use_part_count_limit) {
const std::vector<int> &ready_parts, bool use_part_count_limit, bool is_upload) {
CHECK(expected_size >= size);
is_upload_ = is_upload;
use_part_count_limit_ = use_part_count_limit;
expected_size_ = expected_size;
if (expected_size_ > MAX_FILE_SIZE) {
@ -287,6 +288,7 @@ Result<Part> PartsManager::start_part() {
Status PartsManager::set_known_prefix(size_t size, bool is_ready) {
if (!known_prefix_flag_ || size < static_cast<size_t>(known_prefix_size_)) {
CHECK(is_upload_);
return Status::Error("FILE_UPLOAD_RESTART");
}
known_prefix_size_ = narrow_cast<int64>(size);
@ -307,6 +309,7 @@ Status PartsManager::set_known_prefix(size_t size, bool is_ready) {
<< size << " " << is_ready << " " << part_count_ << " " << part_size_ << " " << part_status_.size();
part_status_.resize(part_count_);
if (use_part_count_limit_ && calc_part_count(expected_size_, part_size_) > MAX_PART_COUNT) {
CHECK(is_upload_);
return Status::Error("FILE_UPLOAD_RESTART");
}
return Status::OK();
@ -454,15 +457,19 @@ Status PartsManager::init_common(const std::vector<int> &ready_parts) {
part_status_ = vector<PartStatus>(part_count_);
for (auto i : ready_parts) {
if (known_prefix_flag_ && i >= static_cast<int>(known_prefix_size_ / part_size_)) {
CHECK(is_upload_);
return Status::Error("FILE_UPLOAD_RESTART");
}
if (is_upload_ && i >= part_count_) {
return Status::Error("FILE_UPLOAD_RESTART");
}
LOG_CHECK(0 <= i && i < part_count_) << tag("i", i) << tag("part_count", part_count_) << tag("size", size_)
<< tag("part_size", part_size_) << tag("known_prefix_flag", known_prefix_flag_)
<< tag("known_prefix_size", known_prefix_size_)
<< tag("real part_count",
std::accumulate(ready_parts.begin(), ready_parts.end(), 0,
[](auto a, auto b) { return max(a, b + 1); }));
if (known_prefix_flag_ && i >= static_cast<int>(known_prefix_size_ / part_size_)) {
return Status::Error("FILE_UPLOAD_RESTART");
}
part_status_[i] = PartStatus::Ready;
bitmask_.set(i);
auto part = get_part(i);

View File

@ -23,7 +23,7 @@ struct Part {
class PartsManager {
public:
Status init(int64 size, int64 expected_size, bool is_size_final, size_t part_size,
const std::vector<int> &ready_parts, bool use_part_count_limit) TD_WARN_UNUSED_RESULT;
const std::vector<int> &ready_parts, bool use_part_count_limit, bool is_upload) TD_WARN_UNUSED_RESULT;
bool may_finish();
bool ready();
bool unchecked_ready();
@ -60,6 +60,7 @@ class PartsManager {
enum class PartStatus : int32 { Empty, Pending, Ready };
bool is_upload_{false};
bool need_check_{false};
int64 checked_prefix_size_{0};

View File

@ -11,6 +11,7 @@
#include "td/telegram/Client.h"
#include "td/telegram/ClientActor.h"
#include "td/telegram/files/PartsManager.h"
#include "td/telegram/td_api.h"
@ -895,4 +896,18 @@ TEST(Client, Multi) {
}
}
TEST(PartsManager, hands) {
//Status init(int64 size, int64 expected_size, bool is_size_final, size_t part_size,
//const std::vector<int> &ready_parts, bool use_part_count_limit) TD_WARN_UNUSED_RESULT;
{
PartsManager pm;
pm.init(0, 100000, false, 10, {0, 1, 2}, false, true).ensure_error();
//pm.set_known_prefix(0, false).ensure();
}
{
PartsManager pm;
pm.init(1, 100000, true, 10, {0, 1, 2}, false, true).ensure_error();
}
}
} // namespace td