mirror of
https://github.com/JulianGro/overte.git
synced 2025-08-07 23:39:54 +02:00
Merge pull request #7475 from birarda/udt-fixes
guard long sleeps in udt::SendQueue
This commit is contained in:
commit
306425b940
4 changed files with 39 additions and 9 deletions
|
@ -81,6 +81,8 @@ AccountManager::AccountManager() :
|
||||||
|
|
||||||
qRegisterMetaType<QHttpMultiPart*>("QHttpMultiPart*");
|
qRegisterMetaType<QHttpMultiPart*>("QHttpMultiPart*");
|
||||||
|
|
||||||
|
qRegisterMetaType<AccountManagerAuth::Type>();
|
||||||
|
|
||||||
connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged);
|
connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,12 +217,13 @@ void AccountManager::sendRequest(const QString& path,
|
||||||
if (thread() != QThread::currentThread()) {
|
if (thread() != QThread::currentThread()) {
|
||||||
QMetaObject::invokeMethod(this, "sendRequest",
|
QMetaObject::invokeMethod(this, "sendRequest",
|
||||||
Q_ARG(const QString&, path),
|
Q_ARG(const QString&, path),
|
||||||
Q_ARG(AccountManagerAuth::Type, AccountManagerAuth::Required),
|
Q_ARG(AccountManagerAuth::Type, authType),
|
||||||
Q_ARG(QNetworkAccessManager::Operation, operation),
|
Q_ARG(QNetworkAccessManager::Operation, operation),
|
||||||
Q_ARG(const JSONCallbackParameters&, callbackParams),
|
Q_ARG(const JSONCallbackParameters&, callbackParams),
|
||||||
Q_ARG(const QByteArray&, dataByteArray),
|
Q_ARG(const QByteArray&, dataByteArray),
|
||||||
Q_ARG(QHttpMultiPart*, dataMultiPart),
|
Q_ARG(QHttpMultiPart*, dataMultiPart),
|
||||||
Q_ARG(QVariantMap, propertyMap));
|
Q_ARG(QVariantMap, propertyMap));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
|
||||||
|
|
|
@ -58,8 +58,6 @@ void UserActivityLogger::logAction(QString action, QJsonObject details, JSONCall
|
||||||
|
|
||||||
// if no callbacks specified, call our owns
|
// if no callbacks specified, call our owns
|
||||||
if (params.isEmpty()) {
|
if (params.isEmpty()) {
|
||||||
params.jsonCallbackReceiver = this;
|
|
||||||
params.jsonCallbackMethod = "requestFinished";
|
|
||||||
params.errorCallbackReceiver = this;
|
params.errorCallbackReceiver = this;
|
||||||
params.errorCallbackMethod = "requestError";
|
params.errorCallbackMethod = "requestError";
|
||||||
}
|
}
|
||||||
|
@ -70,10 +68,6 @@ void UserActivityLogger::logAction(QString action, QJsonObject details, JSONCall
|
||||||
params, NULL, multipart);
|
params, NULL, multipart);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserActivityLogger::requestFinished(QNetworkReply& requestReply) {
|
|
||||||
// qCDebug(networking) << object;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UserActivityLogger::requestError(QNetworkReply& errorReply) {
|
void UserActivityLogger::requestError(QNetworkReply& errorReply) {
|
||||||
qCDebug(networking) << errorReply.error() << "-" << errorReply.errorString();
|
qCDebug(networking) << errorReply.error() << "-" << errorReply.errorString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ public slots:
|
||||||
void wentTo(QString destinationType, QString destinationName);
|
void wentTo(QString destinationType, QString destinationName);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void requestFinished(QNetworkReply& requestReply);
|
|
||||||
void requestError(QNetworkReply& errorReply);
|
void requestError(QNetworkReply& errorReply);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
#include <QtCore/QDateTime>
|
#include <QtCore/QDateTime>
|
||||||
|
#include <QtCore/QJsonObject>
|
||||||
#include <QtCore/QThread>
|
#include <QtCore/QThread>
|
||||||
|
|
||||||
#include <LogHandler.h>
|
#include <LogHandler.h>
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
#include "ControlPacket.h"
|
#include "ControlPacket.h"
|
||||||
#include "Packet.h"
|
#include "Packet.h"
|
||||||
#include "PacketList.h"
|
#include "PacketList.h"
|
||||||
|
#include "../UserActivityLogger.h"
|
||||||
#include "Socket.h"
|
#include "Socket.h"
|
||||||
|
|
||||||
using namespace udt;
|
using namespace udt;
|
||||||
|
@ -328,7 +330,39 @@ void SendQueue::run() {
|
||||||
nextPacketTimestamp += std::chrono::microseconds(nextPacketDelta);
|
nextPacketTimestamp += std::chrono::microseconds(nextPacketDelta);
|
||||||
|
|
||||||
// sleep as long as we need until next packet send, if we can
|
// sleep as long as we need until next packet send, if we can
|
||||||
const auto timeToSleep = duration_cast<microseconds>(nextPacketTimestamp - p_high_resolution_clock::now());
|
auto now = p_high_resolution_clock::now();
|
||||||
|
auto timeToSleep = duration_cast<microseconds>(nextPacketTimestamp - now);
|
||||||
|
|
||||||
|
// we're seeing SendQueues sleep for a long period of time here,
|
||||||
|
// which can lock the NodeList if it's attempting to clear connections
|
||||||
|
// for now we guard this by capping the time this thread and sleep for
|
||||||
|
|
||||||
|
const microseconds MAX_SEND_QUEUE_SLEEP_USECS { 2000000 };
|
||||||
|
if (timeToSleep > MAX_SEND_QUEUE_SLEEP_USECS) {
|
||||||
|
qWarning() << "udt::SendQueue wanted to sleep for" << timeToSleep.count() << "microseconds";
|
||||||
|
qWarning() << "Capping sleep to" << MAX_SEND_QUEUE_SLEEP_USECS.count();
|
||||||
|
qWarning() << "PSP:" << _packetSendPeriod << "NPD:" << nextPacketDelta
|
||||||
|
<< "NPT:" << nextPacketTimestamp.time_since_epoch().count()
|
||||||
|
<< "NOW:" << now.time_since_epoch().count();
|
||||||
|
|
||||||
|
// alright, we're in a weird state
|
||||||
|
// we want to know why this is happening so we can implement a better fix than this guard
|
||||||
|
// send some details up to the API (if the user allows us) that indicate how we could such a large timeToSleep
|
||||||
|
static const QString SEND_QUEUE_LONG_SLEEP_ACTION = "sendqueue-sleep";
|
||||||
|
|
||||||
|
// setup a json object with the details we want
|
||||||
|
QJsonObject longSleepObject;
|
||||||
|
longSleepObject["timeToSleep"] = qint64(timeToSleep.count());
|
||||||
|
longSleepObject["packetSendPeriod"] = _packetSendPeriod.load();
|
||||||
|
longSleepObject["nextPacketDelta"] = nextPacketDelta;
|
||||||
|
longSleepObject["nextPacketTimestamp"] = qint64(nextPacketTimestamp.time_since_epoch().count());
|
||||||
|
longSleepObject["then"] = qint64(now.time_since_epoch().count());
|
||||||
|
|
||||||
|
// hopefully send this event using the user activity logger
|
||||||
|
UserActivityLogger::getInstance().logAction(SEND_QUEUE_LONG_SLEEP_ACTION, longSleepObject);
|
||||||
|
|
||||||
|
timeToSleep = MAX_SEND_QUEUE_SLEEP_USECS;
|
||||||
|
}
|
||||||
|
|
||||||
std::this_thread::sleep_for(timeToSleep);
|
std::this_thread::sleep_for(timeToSleep);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue