Handle the new FLOOD_PREMIUM_WAIT errors.

This commit is contained in:
John Preston 2024-03-28 13:46:30 +04:00
parent 05a5e62327
commit 0dd1a4973a
3 changed files with 42 additions and 9 deletions

View File

@ -99,6 +99,9 @@ public:
void restartedByTimeout(ShiftedDcId shiftedDcId);
[[nodiscard]] rpl::producer<ShiftedDcId> restartsByTimeout() const;
[[nodiscard]] auto nonPremiumDelayedRequests() const
-> rpl::producer<mtpRequestId>;
void restart();
void restart(ShiftedDcId shiftedDcId);
[[nodiscard]] int32 dcstate(ShiftedDcId shiftedDcId = 0);
@ -283,6 +286,8 @@ private:
Fn<void(ShiftedDcId shiftedDcId, int32 state)> _stateChangedHandler;
Fn<void(ShiftedDcId shiftedDcId)> _sessionResetHandler;
rpl::event_stream<mtpRequestId> _nonPremiumDelayedRequests;
base::Timer _checkDelayedTimer;
Core::SettingsProxy &_proxySettings;
@ -553,6 +558,11 @@ rpl::producer<ShiftedDcId> Instance::Private::restartsByTimeout() const {
return _restartsByTimeout.events();
}
auto Instance::Private::nonPremiumDelayedRequests() const
-> rpl::producer<mtpRequestId> {
return _nonPremiumDelayedRequests.events();
}
void Instance::Private::requestConfigIfOld() {
const auto timeout = _config->values().blockedMode
? kConfigBecomesOldForBlockedIn
@ -1356,8 +1366,9 @@ bool Instance::Private::onErrorDefault(
auto badGuestDc = (code == 400) && (type == u"FILE_ID_INVALID"_q);
static const auto MigrateRegExp = QRegularExpression("^(FILE|PHONE|NETWORK|USER)_MIGRATE_(\\d+)$");
static const auto FloodWaitRegExp = QRegularExpression("^FLOOD_WAIT_(\\d+)$");
static const auto FloodPremiumWaitRegExp = QRegularExpression("^FLOOD_PREMIUM_WAIT_(\\d+)$");
static const auto SlowmodeWaitRegExp = QRegularExpression("^SLOWMODE_WAIT_(\\d+)$");
QRegularExpressionMatch m1, m2;
QRegularExpressionMatch m1, m2, m3;
if ((m1 = MigrateRegExp.match(type)).hasMatch()) {
if (!requestId) return false;
@ -1462,13 +1473,17 @@ bool Instance::Private::onErrorDefault(
} else if (code < 0
|| code >= 500
|| (m1 = FloodWaitRegExp.match(type)).hasMatch()
|| ((m2 = SlowmodeWaitRegExp.match(type)).hasMatch()
&& m2.captured(1).toInt() < 3)) {
if (!requestId) return false;
|| (m2 = FloodPremiumWaitRegExp.match(type)).hasMatch()
|| ((m3 = SlowmodeWaitRegExp.match(type)).hasMatch()
&& m3.captured(1).toInt() < 3)) {
if (!requestId) {
return false;
}
int32 secs = 1;
auto secs = 1;
auto nonPremiumDelay = false;
if (code < 0 || code >= 500) {
auto it = _requestsDelays.find(requestId);
const auto it = _requestsDelays.find(requestId);
if (it != _requestsDelays.cend()) {
secs = (it->second > 60) ? it->second : (it->second *= 2);
} else {
@ -1479,17 +1494,27 @@ bool Instance::Private::onErrorDefault(
// if (secs >= 60) return false;
} else if (m2.hasMatch()) {
secs = m2.captured(1).toInt();
nonPremiumDelay = true;
} else if (m3.hasMatch()) {
secs = m3.captured(1).toInt();
}
auto sendAt = crl::now() + secs * 1000 + 10;
auto it = _delayedRequests.begin(), e = _delayedRequests.end();
for (; it != e; ++it) {
if (it->first == requestId) return true;
if (it->second > sendAt) break;
if (it->first == requestId) {
return true;
} else if (it->second > sendAt) {
break;
}
}
_delayedRequests.insert(it, std::make_pair(requestId, sendAt));
checkDelayedRequests();
if (nonPremiumDelay) {
_nonPremiumDelayedRequests.fire_copy(requestId);
}
return true;
} else if ((code == 401 && type != u"AUTH_KEY_PERM_EMPTY"_q)
|| (badGuestDc && _badGuestDcRequests.find(requestId) == _badGuestDcRequests.cend())) {
@ -1879,6 +1904,10 @@ rpl::producer<ShiftedDcId> Instance::restartsByTimeout() const {
return _private->restartsByTimeout();
}
rpl::producer<mtpRequestId> Instance::nonPremiumDelayedRequests() const {
return _private->nonPremiumDelayedRequests();
}
void Instance::requestConfigIfOld() {
_private->requestConfigIfOld();
}

View File

@ -140,6 +140,9 @@ public:
void restartedByTimeout(ShiftedDcId shiftedDcId);
[[nodiscard]] rpl::producer<ShiftedDcId> restartsByTimeout() const;
[[nodiscard]] auto nonPremiumDelayedRequests() const
-> rpl::producer<mtpRequestId>;
void syncHttpUnixtime();
void sendAnything(ShiftedDcId shiftedDcId = 0, crl::time msCanWait = 0);

View File

@ -39,7 +39,8 @@ private:
};
inline bool IsFloodError(const QString &type) {
return type.startsWith(u"FLOOD_WAIT_"_q);
return type.startsWith(u"FLOOD_WAIT_"_q)
|| type.startsWith(u"FLOOD_PREMIUM_WAIT_"_q);
}
inline bool IsFloodError(const Error &error) {