Allow skipping stuck files in data export.

Fixes #6423.
This commit is contained in:
John Preston
2021-03-22 16:32:40 +04:00
parent 12db51fe75
commit 03a868a6e3
11 changed files with 150 additions and 22 deletions
+46 -12
View File
@@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/mtproto_response.h"
#include "base/value_ordering.h"
#include "base/bytes.h"
#include "base/openssl_help.h"
#include <set>
#include <deque>
@@ -182,6 +183,7 @@ struct ApiWrap::FileProcess {
Fn<bool(FileProgress)> progress;
FnMut<void(const QString &relativePath)> done;
uint64 randomId = 0;
Data::FileLocation location;
Data::FileOrigin origin;
int offset = 0;
@@ -192,6 +194,7 @@ struct ApiWrap::FileProcess {
QByteArray bytes;
};
std::deque<Request> requests;
mtpRequestId requestId = 0;
};
struct ApiWrap::FileProgress {
@@ -383,6 +386,7 @@ auto ApiWrap::fileRequest(const Data::FileLocation &location, int offset) {
Expects(location.dcId != 0
|| location.data.type() == mtpc_inputTakeoutFileLocation);
Expects(_takeoutId.has_value());
Expects(_fileProcess->requestId == 0);
return std::move(_mtp.request(MTPInvokeWithTakeout<MTPupload_GetFile>(
MTP_long(*_takeoutId),
@@ -392,6 +396,7 @@ auto ApiWrap::fileRequest(const Data::FileLocation &location, int offset) {
MTP_int(offset),
MTP_int(kFileChunkSize))
)).fail([=](const MTP::Error &result) {
_fileProcess->requestId = 0;
if (result.type() == qstr("TAKEOUT_FILE_EMPTY")
&& _otherDataProcess != nullptr) {
filePartDone(
@@ -853,6 +858,7 @@ bool ApiWrap::loadUserpicProgress(FileProgress progress) {
< _userpicsProcess->slice->list.size()));
return _userpicsProcess->fileProgress(DownloadProgress{
_fileProcess->randomId,
_fileProcess->relativePath,
_userpicsProcess->fileIndex,
progress.ready,
@@ -1061,6 +1067,17 @@ void ApiWrap::finishExport(FnMut<void()> done) {
)).done(std::move(done)).send();
}
void ApiWrap::skipFile(uint64 randomId) {
if (!_fileProcess || _fileProcess->randomId != randomId) {
return;
}
LOG(("Export Info: File skipped."));
Assert(!_fileProcess->requests.empty());
Assert(_fileProcess->requestId != 0);
_mtp.request(base::take(_fileProcess->requestId)).cancel();
base::take(_fileProcess)->done(QString());
}
void ApiWrap::cancelExportFast() {
if (_takeoutId.has_value()) {
const auto requestId = mainRequest(MTPaccount_FinishTakeoutSession(
@@ -1591,10 +1608,11 @@ bool ApiWrap::loadMessageFileProgress(FileProgress progress) {
&& (_chatProcess->fileIndex < _chatProcess->slice->list.size()));
return _chatProcess->fileProgress(DownloadProgress{
_fileProcess->relativePath,
_chatProcess->fileIndex,
progress.ready,
progress.total });
.randomId = _fileProcess->randomId,
.path = _fileProcess->relativePath,
.itemIndex = _chatProcess->fileIndex,
.ready = progress.ready,
.total = progress.total });
}
void ApiWrap::loadMessageFileDone(const QString &relativePath) {
@@ -1740,6 +1758,8 @@ void ApiWrap::loadFile(
}
loadFilePart();
Ensures(_fileProcess->requestId != 0);
}
auto ApiWrap::prepareFileProcess(
@@ -1758,11 +1778,13 @@ auto ApiWrap::prepareFileProcess(
result->location = file.location;
result->size = file.size;
result->origin = origin;
result->randomId = openssl::RandomValue<uint64>();
return result;
}
void ApiWrap::loadFilePart() {
if (!_fileProcess
|| _fileProcess->requestId
|| _fileProcess->requests.size() >= kFileRequestsCount
|| (_fileProcess->size > 0
&& _fileProcess->offset >= _fileProcess->size)) {
@@ -1771,16 +1793,18 @@ void ApiWrap::loadFilePart() {
const auto offset = _fileProcess->offset;
_fileProcess->requests.push_back({ offset });
fileRequest(
_fileProcess->requestId = fileRequest(
_fileProcess->location,
_fileProcess->offset
).done([=](const MTPupload_File &result) {
_fileProcess->requestId = 0;
filePartDone(offset, result);
}).send();
_fileProcess->offset += kFileChunkSize;
if (_fileProcess->size > 0
&& _fileProcess->requests.size() < kFileRequestsCount) {
// Only one request at a time supported right now.
//const auto runner = _runner;
//crl::on_main([=] {
// QTimer::singleShot(kFileNextRequestDelay, [=] {
@@ -1854,6 +1878,7 @@ void ApiWrap::filePartDone(int offset, const MTPupload_File &result) {
void ApiWrap::filePartRefreshReference(int offset) {
Expects(_fileProcess != nullptr);
Expects(_fileProcess->requestId == 0);
const auto &origin = _fileProcess->origin;
if (!origin.messageId) {
@@ -1870,26 +1895,33 @@ void ApiWrap::filePartRefreshReference(int offset) {
origin.peer.c_inputPeerChannelFromMessage().vpeer(),
origin.peer.c_inputPeerChannelFromMessage().vmsg_id(),
origin.peer.c_inputPeerChannelFromMessage().vchannel_id());
mainRequest(MTPchannels_GetMessages(
_fileProcess->requestId = mainRequest(MTPchannels_GetMessages(
channel,
MTP_vector<MTPInputMessage>(
1,
MTP_inputMessageID(MTP_int(origin.messageId)))
)).fail([=](const MTP::Error &error) {
_fileProcess->requestId = 0;
filePartUnavailable();
return true;
}).done([=](const MTPmessages_Messages &result) {
_fileProcess->requestId = 0;
filePartExtractReference(offset, result);
}).send();
} else {
splitRequest(origin.split, MTPmessages_GetMessages(
MTP_vector<MTPInputMessage>(
1,
MTP_inputMessageID(MTP_int(origin.messageId)))
)).fail([=](const MTP::Error &error) {
_fileProcess->requestId = splitRequest(
origin.split,
MTPmessages_GetMessages(
MTP_vector<MTPInputMessage>(
1,
MTP_inputMessageID(MTP_int(origin.messageId)))
)
).fail([=](const MTP::Error &error) {
_fileProcess->requestId = 0;
filePartUnavailable();
return true;
}).done([=](const MTPmessages_Messages &result) {
_fileProcess->requestId = 0;
filePartExtractReference(offset, result);
}).send();
}
@@ -1899,6 +1931,7 @@ void ApiWrap::filePartExtractReference(
int offset,
const MTPmessages_Messages &result) {
Expects(_fileProcess != nullptr);
Expects(_fileProcess->requestId == 0);
result.match([&](const MTPDmessages_messagesNotModified &data) {
error("Unexpected messagesNotModified received.");
@@ -1922,10 +1955,11 @@ void ApiWrap::filePartExtractReference(
_fileProcess->location,
message.thumb().file.location);
if (refresh1 || refresh2) {
fileRequest(
_fileProcess->requestId = fileRequest(
_fileProcess->location,
offset
).done([=](const MTPupload_File &result) {
_fileProcess->requestId = 0;
filePartDone(offset, result);
}).send();
return;