mirror of https://github.com/procxx/kepka.git
Check request duration when adding sessions.
This commit is contained in:
parent
e426f2895b
commit
7fb24d77c0
|
@ -18,7 +18,8 @@ namespace Storage {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kKillSessionTimeout = 15 * crl::time(1000);
|
constexpr auto kKillSessionTimeout = 15 * crl::time(1000);
|
||||||
constexpr auto kMaxWaitedInSession = 2 * 1024 * 1024;
|
constexpr auto kStartWaitedInSession = 4 * kDownloadPartSize;
|
||||||
|
constexpr auto kMaxWaitedInSession = 16 * kDownloadPartSize;
|
||||||
constexpr auto kStartSessionsCount = 1;
|
constexpr auto kStartSessionsCount = 1;
|
||||||
constexpr auto kMaxSessionsCount = 8;
|
constexpr auto kMaxSessionsCount = 8;
|
||||||
constexpr auto kMaxTrackedSessionRemoves = 64;
|
constexpr auto kMaxTrackedSessionRemoves = 64;
|
||||||
|
@ -28,10 +29,13 @@ constexpr auto kMaxTrackedSuccesses = kRetryAddSessionSuccesses
|
||||||
* kMaxTrackedSessionRemoves;
|
* kMaxTrackedSessionRemoves;
|
||||||
constexpr auto kRemoveSessionAfterTimeouts = 2;
|
constexpr auto kRemoveSessionAfterTimeouts = 2;
|
||||||
constexpr auto kResetDownloadPrioritiesTimeout = crl::time(200);
|
constexpr auto kResetDownloadPrioritiesTimeout = crl::time(200);
|
||||||
|
constexpr auto kGrowMaxWaitedDurationThreshold = crl::time(500);
|
||||||
|
constexpr auto kGrowSessionsDurationThreshold = crl::time(500);
|
||||||
|
constexpr auto kBadRequestDurationThreshold = crl::time(2000);
|
||||||
|
|
||||||
// Each session remove by timeouts we wait for time
|
// Each (session remove by timeouts) we wait for time:
|
||||||
// kRetryAddSessionTimeout * max(removesCount, kMaxTrackedSessionRemoves)
|
// kRetryAddSessionTimeout * max(removesCount, kMaxTrackedSessionRemoves)
|
||||||
// and for successes in all remaining sessions
|
// and for successes in all remaining sessions:
|
||||||
// kRetryAddSessionSuccesses * max(removesCount, kMaxTrackedSessionRemoves)
|
// kRetryAddSessionSuccesses * max(removesCount, kMaxTrackedSessionRemoves)
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -77,7 +81,7 @@ auto DownloadManagerMtproto::Queue::nextTask() const -> Task* {
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadManagerMtproto::DcSessionBalanceData::DcSessionBalanceData()
|
DownloadManagerMtproto::DcSessionBalanceData::DcSessionBalanceData()
|
||||||
: maxWaitedAmount(kDownloadPartSize) {
|
: maxWaitedAmount(kStartWaitedInSession) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DownloadManagerMtproto::DcBalanceData::DcBalanceData()
|
DownloadManagerMtproto::DcBalanceData::DcBalanceData()
|
||||||
|
@ -184,19 +188,44 @@ void DownloadManagerMtproto::changeRequestedAmount(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadManagerMtproto::requestSucceeded(MTP::DcId dcId, int index) {
|
void DownloadManagerMtproto::requestSucceeded(
|
||||||
|
MTP::DcId dcId,
|
||||||
|
int index,
|
||||||
|
crl::time duration) {
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
|
|
||||||
DEBUG_LOG(("Download (%1,%2) request done.").arg(dcId).arg(index));
|
DEBUG_LOG(("Download (%1,%2) request done, duration %3."
|
||||||
|
).arg(dcId
|
||||||
|
).arg(index
|
||||||
|
).arg(duration));
|
||||||
const auto i = _balanceData.find(dcId);
|
const auto i = _balanceData.find(dcId);
|
||||||
Assert(i != end(_balanceData));
|
Assert(i != end(_balanceData));
|
||||||
auto &dc = i->second;
|
auto &dc = i->second;
|
||||||
Assert(index < dc.sessions.size());
|
Assert(index < dc.sessions.size());
|
||||||
auto &data = dc.sessions[index];
|
auto &data = dc.sessions[index];
|
||||||
|
const auto guard = gsl::finally([&] {
|
||||||
|
checkSendNext(dcId, _queues[dcId]);
|
||||||
|
});
|
||||||
|
const auto parts = data.maxWaitedAmount / kDownloadPartSize;
|
||||||
|
if (duration < kGrowMaxWaitedDurationThreshold * parts) {
|
||||||
|
if (data.maxWaitedAmount < kMaxWaitedInSession) {
|
||||||
|
data.maxWaitedAmount = std::min(
|
||||||
|
data.maxWaitedAmount + kDownloadPartSize,
|
||||||
|
kMaxWaitedInSession);
|
||||||
|
DEBUG_LOG(("Download (%1,%2) increased max waited amount %3."
|
||||||
|
).arg(dcId
|
||||||
|
).arg(index
|
||||||
|
).arg(data.maxWaitedAmount));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (duration >= kBadRequestDurationThreshold * parts) {
|
||||||
|
DEBUG_LOG(("Duration too large, signaling time out."));
|
||||||
|
sessionTimedOut(dcId, index);
|
||||||
|
return;
|
||||||
|
} else if (duration >= kGrowSessionsDurationThreshold * parts) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
data.successes = std::min(data.successes + 1, kMaxTrackedSuccesses);
|
data.successes = std::min(data.successes + 1, kMaxTrackedSuccesses);
|
||||||
data.maxWaitedAmount = std::min(
|
|
||||||
data.maxWaitedAmount + kDownloadPartSize,
|
|
||||||
kMaxWaitedInSession);
|
|
||||||
const auto notEnough = ranges::find_if(
|
const auto notEnough = ranges::find_if(
|
||||||
dc.sessions,
|
dc.sessions,
|
||||||
_1 < (dc.sessionRemoveTimes + 1) * kRetryAddSessionSuccesses,
|
_1 < (dc.sessionRemoveTimes + 1) * kRetryAddSessionSuccesses,
|
||||||
|
@ -222,7 +251,6 @@ void DownloadManagerMtproto::requestSucceeded(MTP::DcId dcId, int index) {
|
||||||
).arg(dcId
|
).arg(dcId
|
||||||
).arg(dc.sessions.size()));
|
).arg(dc.sessions.size()));
|
||||||
dc.sessions.emplace_back();
|
dc.sessions.emplace_back();
|
||||||
checkSendNext(dcId, _queues[dcId]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DownloadManagerMtproto::sessionTimedOut(MTP::DcId dcId, int index) {
|
void DownloadManagerMtproto::sessionTimedOut(MTP::DcId dcId, int index) {
|
||||||
|
@ -588,8 +616,6 @@ void DownloadMtprotoTask::getCdnFileHashesDone(
|
||||||
mtpRequestId requestId) {
|
mtpRequestId requestId) {
|
||||||
Expects(_cdnHashesRequestId == requestId);
|
Expects(_cdnHashesRequestId == requestId);
|
||||||
|
|
||||||
_cdnHashesRequestId = 0;
|
|
||||||
|
|
||||||
const auto requestData = finishSentRequest(
|
const auto requestData = finishSentRequest(
|
||||||
requestId,
|
requestId,
|
||||||
FinishRequestReason::Redirect);
|
FinishRequestReason::Redirect);
|
||||||
|
@ -648,6 +674,8 @@ void DownloadMtprotoTask::placeSentRequest(
|
||||||
requestData.offset,
|
requestData.offset,
|
||||||
requestId);
|
requestId);
|
||||||
|
|
||||||
|
i->second.sent = crl::now();
|
||||||
|
|
||||||
Ensures(ok1 && ok2);
|
Ensures(ok1 && ok2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,6 +686,9 @@ auto DownloadMtprotoTask::finishSentRequest(
|
||||||
auto it = _sentRequests.find(requestId);
|
auto it = _sentRequests.find(requestId);
|
||||||
Assert(it != _sentRequests.cend());
|
Assert(it != _sentRequests.cend());
|
||||||
|
|
||||||
|
if (_cdnHashesRequestId == requestId) {
|
||||||
|
_cdnHashesRequestId = 0;
|
||||||
|
}
|
||||||
const auto result = it->second;
|
const auto result = it->second;
|
||||||
_owner->changeRequestedAmount(
|
_owner->changeRequestedAmount(
|
||||||
dcId(),
|
dcId(),
|
||||||
|
@ -667,7 +698,8 @@ auto DownloadMtprotoTask::finishSentRequest(
|
||||||
const auto ok = _requestByOffset.remove(result.offset);
|
const auto ok = _requestByOffset.remove(result.offset);
|
||||||
|
|
||||||
if (reason == FinishRequestReason::Success) {
|
if (reason == FinishRequestReason::Success) {
|
||||||
_owner->requestSucceeded(dcId(), result.dcIndex);
|
const auto duration = crl::now() - result.sent;
|
||||||
|
_owner->requestSucceeded(dcId(), result.dcIndex, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ensures(ok);
|
Ensures(ok);
|
||||||
|
@ -755,9 +787,6 @@ bool DownloadMtprotoTask::cdnPartFailed(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requestId == _cdnHashesRequestId) {
|
|
||||||
_cdnHashesRequestId = 0;
|
|
||||||
}
|
|
||||||
if (error.type() == qstr("FILE_TOKEN_INVALID")
|
if (error.type() == qstr("FILE_TOKEN_INVALID")
|
||||||
|| error.type() == qstr("REQUEST_TOKEN_INVALID")) {
|
|| error.type() == qstr("REQUEST_TOKEN_INVALID")) {
|
||||||
const auto requestData = finishSentRequest(
|
const auto requestData = finishSentRequest(
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void changeRequestedAmount(MTP::DcId dcId, int index, int delta);
|
void changeRequestedAmount(MTP::DcId dcId, int index, int delta);
|
||||||
void requestSucceeded(MTP::DcId dcId, int index);
|
void requestSucceeded(MTP::DcId dcId, int index, crl::time duration);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Queue final {
|
class Queue final {
|
||||||
|
@ -153,6 +153,7 @@ private:
|
||||||
struct RequestData {
|
struct RequestData {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int dcIndex = 0;
|
int dcIndex = 0;
|
||||||
|
crl::time sent = 0;
|
||||||
|
|
||||||
inline bool operator<(const RequestData &other) const {
|
inline bool operator<(const RequestData &other) const {
|
||||||
return offset < other.offset;
|
return offset < other.offset;
|
||||||
|
|
Loading…
Reference in New Issue