mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Handle MSG_WAIT_FAILED / MSG_WAIT_TIMEOUT.
This commit is contained in:
parent
bae8335285
commit
e28fb1211e
2 changed files with 87 additions and 75 deletions
|
@ -264,6 +264,8 @@ private:
|
||||||
QReadWriteLock _requestMapLock;
|
QReadWriteLock _requestMapLock;
|
||||||
|
|
||||||
std::deque<std::pair<mtpRequestId, crl::time>> _delayedRequests;
|
std::deque<std::pair<mtpRequestId, crl::time>> _delayedRequests;
|
||||||
|
base::flat_map<mtpRequestId, mtpRequestId> _dependentRequests;
|
||||||
|
mutable QMutex _dependentRequestsLock;
|
||||||
|
|
||||||
std::map<mtpRequestId, int> _requestsDelays;
|
std::map<mtpRequestId, int> _requestsDelays;
|
||||||
|
|
||||||
|
@ -1010,9 +1012,40 @@ void Instance::Private::unregisterRequest(mtpRequestId requestId) {
|
||||||
QWriteLocker locker(&_requestMapLock);
|
QWriteLocker locker(&_requestMapLock);
|
||||||
_requestMap.erase(requestId);
|
_requestMap.erase(requestId);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&_requestByDcLock);
|
||||||
|
_requestsByDc.erase(requestId);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&_dependentRequestsLock);
|
||||||
|
for (auto i = begin(_dependentRequests); i != end(_dependentRequests);) {
|
||||||
|
if (i->first == requestId) {
|
||||||
|
i = _dependentRequests.erase(i);
|
||||||
|
} else if (i->second == requestId) {
|
||||||
|
const auto resendingId = i->first;
|
||||||
|
i = _dependentRequests.erase(i);
|
||||||
|
|
||||||
QMutexLocker locker(&_requestByDcLock);
|
if (const auto shiftedDcId = queryRequestByDc(resendingId)) {
|
||||||
_requestsByDc.erase(requestId);
|
SerializedRequest request;
|
||||||
|
{
|
||||||
|
QReadLocker locker(&_requestMapLock);
|
||||||
|
auto it = _requestMap.find(resendingId);
|
||||||
|
if (it == _requestMap.cend()) {
|
||||||
|
LOG(("MTP Error: could not find dependent request %1").arg(resendingId));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
request = it->second;
|
||||||
|
}
|
||||||
|
request->after = SerializedRequest();
|
||||||
|
const auto session = getSession(qAbs(*shiftedDcId));
|
||||||
|
request->needsLayer = true;
|
||||||
|
session->sendPrepared(request);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::Private::storeRequest(
|
void Instance::Private::storeRequest(
|
||||||
|
@ -1339,6 +1372,47 @@ bool Instance::Private::onErrorDefault(
|
||||||
(dcWithShift < 0) ? -newdcWithShift : newdcWithShift);
|
(dcWithShift < 0) ? -newdcWithShift : newdcWithShift);
|
||||||
session->sendPrepared(request);
|
session->sendPrepared(request);
|
||||||
return true;
|
return true;
|
||||||
|
} else if (type == qstr("MSG_WAIT_TIMEOUT") || type == qstr("MSG_WAIT_FAILED")) {
|
||||||
|
SerializedRequest request;
|
||||||
|
{
|
||||||
|
QReadLocker locker(&_requestMapLock);
|
||||||
|
auto it = _requestMap.find(requestId);
|
||||||
|
if (it == _requestMap.cend()) {
|
||||||
|
LOG(("MTP Error: could not find MSG_WAIT_* request %1").arg(requestId));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
request = it->second;
|
||||||
|
}
|
||||||
|
if (!request->after) {
|
||||||
|
LOG(("MTP Error: MSG_WAIT_* for not dependent request %1").arg(requestId));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto dcWithShift = ShiftedDcId(0);
|
||||||
|
if (const auto shiftedDcId = queryRequestByDc(requestId)) {
|
||||||
|
dcWithShift = *shiftedDcId;
|
||||||
|
if (const auto afterDcId = queryRequestByDc(request->after->requestId)) {
|
||||||
|
if (*shiftedDcId != *afterDcId) {
|
||||||
|
request->after = SerializedRequest();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
request->after = SerializedRequest();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LOG(("MTP Error: could not find MSG_WAIT_* request %1 by dc").arg(requestId));
|
||||||
|
}
|
||||||
|
if (!dcWithShift) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!request->after) {
|
||||||
|
const auto session = getSession(qAbs(dcWithShift));
|
||||||
|
request->needsLayer = true;
|
||||||
|
session->sendPrepared(request);
|
||||||
|
} else {
|
||||||
|
QMutexLocker locker(&_dependentRequestsLock);
|
||||||
|
_dependentRequests.emplace(requestId, request->after->requestId);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
} else if (code < 0
|
} else if (code < 0
|
||||||
|| code >= 500
|
|| code >= 500
|
||||||
|| (m1 = QRegularExpression("^FLOOD_WAIT_(\\d+)$").match(type)).hasMatch()
|
|| (m1 = QRegularExpression("^FLOOD_WAIT_(\\d+)$").match(type)).hasMatch()
|
||||||
|
@ -1435,66 +1509,6 @@ bool Instance::Private::onErrorDefault(
|
||||||
return true;
|
return true;
|
||||||
} else if (type == qstr("CONNECTION_LANG_CODE_INVALID")) {
|
} else if (type == qstr("CONNECTION_LANG_CODE_INVALID")) {
|
||||||
Lang::CurrentCloudManager().resetToDefault();
|
Lang::CurrentCloudManager().resetToDefault();
|
||||||
} else if (type == qstr("MSG_WAIT_FAILED")) {
|
|
||||||
SerializedRequest request;
|
|
||||||
{
|
|
||||||
QReadLocker locker(&_requestMapLock);
|
|
||||||
auto it = _requestMap.find(requestId);
|
|
||||||
if (it == _requestMap.cend()) {
|
|
||||||
LOG(("MTP Error: could not find request %1").arg(requestId));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
request = it->second;
|
|
||||||
}
|
|
||||||
if (!request->after) {
|
|
||||||
LOG(("MTP Error: wait failed for not dependent request %1").arg(requestId));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto dcWithShift = ShiftedDcId(0);
|
|
||||||
if (const auto shiftedDcId = queryRequestByDc(requestId)) {
|
|
||||||
if (const auto afterDcId = queryRequestByDc(request->after->requestId)) {
|
|
||||||
dcWithShift = *shiftedDcId;
|
|
||||||
if (*shiftedDcId != *afterDcId) {
|
|
||||||
request->after = SerializedRequest();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG(("MTP Error: could not find dependent request %1 by dc").arg(request->after->requestId));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG(("MTP Error: could not find request %1 by dc").arg(requestId));
|
|
||||||
}
|
|
||||||
if (!dcWithShift) return false;
|
|
||||||
|
|
||||||
if (!request->after) {
|
|
||||||
const auto session = getSession(qAbs(dcWithShift));
|
|
||||||
request->needsLayer = true;
|
|
||||||
session->sendPrepared(request);
|
|
||||||
} else {
|
|
||||||
auto newdc = BareDcId(qAbs(dcWithShift));
|
|
||||||
auto &waiters(_authWaiters[newdc]);
|
|
||||||
if (base::contains(waiters, request->after->requestId)) {
|
|
||||||
if (!base::contains(waiters, requestId)) {
|
|
||||||
waiters.push_back(requestId);
|
|
||||||
}
|
|
||||||
if (_badGuestDcRequests.find(request->after->requestId) != _badGuestDcRequests.cend()) {
|
|
||||||
if (_badGuestDcRequests.find(requestId) == _badGuestDcRequests.cend()) {
|
|
||||||
_badGuestDcRequests.insert(requestId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
auto i = _delayedRequests.begin(), e = _delayedRequests.end();
|
|
||||||
for (; i != e; ++i) {
|
|
||||||
if (i->first == requestId) return true;
|
|
||||||
if (i->first == request->after->requestId) break;
|
|
||||||
}
|
|
||||||
if (i != e) {
|
|
||||||
_delayedRequests.insert(i, std::make_pair(requestId, i->second));
|
|
||||||
}
|
|
||||||
|
|
||||||
checkDelayedRequests();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
if (badGuestDc) _badGuestDcRequests.erase(requestId);
|
if (badGuestDc) _badGuestDcRequests.erase(requestId);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -25,22 +25,20 @@ namespace {
|
||||||
Error::Error(const MTPrpcError &error)
|
Error::Error(const MTPrpcError &error)
|
||||||
: _code(error.c_rpc_error().verror_code().v) {
|
: _code(error.c_rpc_error().verror_code().v) {
|
||||||
QString text = qs(error.c_rpc_error().verror_message());
|
QString text = qs(error.c_rpc_error().verror_message());
|
||||||
if (_code < 0 || _code >= 500) {
|
const auto expression = QRegularExpression(
|
||||||
|
"^([A-Z0-9_]+)(: .*)?$",
|
||||||
|
(QRegularExpression::DotMatchesEverythingOption
|
||||||
|
| QRegularExpression::MultilineOption));
|
||||||
|
const auto match = expression.match(text);
|
||||||
|
if (match.hasMatch()) {
|
||||||
|
_type = match.captured(1);
|
||||||
|
_description = match.captured(2).mid(2);
|
||||||
|
} else if (_code < 0 || _code >= 500) {
|
||||||
_type = "INTERNAL_SERVER_ERROR";
|
_type = "INTERNAL_SERVER_ERROR";
|
||||||
_description = text;
|
_description = text;
|
||||||
} else {
|
} else {
|
||||||
const auto expression = QRegularExpression(
|
_type = "CLIENT_BAD_RPC_ERROR";
|
||||||
"^([A-Z0-9_]+)(: .*)?$",
|
_description = "Bad rpc error received, text = '" + text + '\'';
|
||||||
(QRegularExpression::DotMatchesEverythingOption
|
|
||||||
| QRegularExpression::MultilineOption));
|
|
||||||
const auto match = expression.match(text);
|
|
||||||
if (match.hasMatch()) {
|
|
||||||
_type = match.captured(1);
|
|
||||||
_description = match.captured(2).mid(2);
|
|
||||||
} else {
|
|
||||||
_type = "CLIENT_BAD_RPC_ERROR";
|
|
||||||
_description = "Bad rpc error received, text = '" + text + '\'';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue