Implement an API rate limiter

This commit is contained in:
Silarn
2019-02-18 21:28:06 -06:00
parent fbbff08fb8
commit b6498abaf3
5 changed files with 44 additions and 4 deletions
+8
View File
@@ -396,6 +396,8 @@ MainWindow::MainWindow(QSettings &initSettings
connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(validateFailed(QString)), this, SLOT(validationFailed(QString)));
connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(credentialsReceived(const QString&, bool)),
this, SLOT(updateWindowTitle(const QString&, bool)));
connect(NexusInterface::instance(&pluginContainer)->getAccessManager(), SIGNAL(credentialsReceived(const QString&, bool)),
NexusInterface::instance(&m_PluginContainer), SLOT(setRateMax(const QString&, bool)));
connect(&TutorialManager::instance(), SIGNAL(windowTutorialFinished(QString)), this, SLOT(windowTutorialFinished(QString)));
connect(ui->tabWidget, SIGNAL(currentChanged(int)), &TutorialManager::instance(), SIGNAL(tabChanged(int)));
@@ -430,6 +432,11 @@ MainWindow::MainWindow(QSettings &initSettings
connect(&m_SaveMetaTimer, SIGNAL(timeout()), this, SLOT(saveModMetas()));
m_SaveMetaTimer.start(5000);
m_NexusLimitTimer.setTimerType(Qt::TimerType::PreciseTimer);
m_NexusLimitTimer.setSingleShot(false);
connect(&m_NexusLimitTimer, SIGNAL(timeout()), NexusInterface::instance(&m_PluginContainer), SLOT(calculateRequests()));
m_NexusLimitTimer.start(1000);
setCategoryListVisible(initSettings.value("categorylist_visible", true).toBool());
FileDialogMemory::restore(initSettings);
@@ -5526,6 +5533,7 @@ void MainWindow::nxmDescriptionAvailable(QString gameName, int modID, QVariant u
std::vector<ModInfo::Ptr> modsList = ModInfo::getByModID(gameName, modID);
for (auto mod : modsList) {
mod->setNexusDescription(result["description"].toString());
mod->setNewestVersion(result["version"].toString());
if ((mod->endorsedState() != ModInfo::ENDORSED_NEVER) && (result.contains("endorsement"))) {
QVariantMap endorsement = result["endorsement"].toMap();
+1
View File
@@ -348,6 +348,7 @@ private:
QTimer m_CheckBSATimer;
QTimer m_SaveMetaTimer;
QTimer m_UpdateProblemsTimer;
QTimer m_NexusLimitTimer;
QFuture<void> m_MetaSave;
+26 -2
View File
@@ -148,7 +148,7 @@ QAtomicInt NexusInterface::NXMRequestInfo::s_NextID(0);
NexusInterface::NexusInterface(PluginContainer *pluginContainer)
: m_NMMVersion(), m_PluginContainer(pluginContainer)
: m_NMMVersion(), m_PluginContainer(pluginContainer), m_RemainingRequests(300), m_MaxRequests(300)
{
m_MOVersion = createVersionInfo();
@@ -190,6 +190,16 @@ void NexusInterface::loginCompleted()
nextRequest();
}
void NexusInterface::setRateMax(const QString &userName, bool isPremium)
{
if (isPremium) {
m_MaxRequests = 600;
m_RemainingRequests = 600;
} else {
m_MaxRequests = 300;
m_RemainingRequests = 300;
}
}
void NexusInterface::interpretNexusFileName(const QString &fileName, QString &modName, int &modID, bool query)
{
@@ -459,6 +469,11 @@ void NexusInterface::nextRequest()
return;
}
if (m_RemainingRequests <= 0) {
qWarning() << tr("You've exceeded the Nexus API rate limit and requests are now being throttled.");
return;
}
if (requiresLogin(m_RequestQueue.head()) && !getAccessManager()->validated()) {
if (!getAccessManager()->validateAttempted()) {
emit needLogin();
@@ -468,6 +483,8 @@ void NexusInterface::nextRequest()
}
}
m_RemainingRequests--;
NXMRequestInfo info = m_RequestQueue.dequeue();
info.m_Timeout = new QTimer(this);
info.m_Timeout->setInterval(60000);
@@ -634,6 +651,12 @@ void NexusInterface::requestTimeout()
}
}
void NexusInterface::calculateRequests()
{
if (m_RemainingRequests < m_MaxRequests)
m_RemainingRequests++;
}
namespace {
QString get_management_url(MOBase::IPluginGame const *game)
{
@@ -661,7 +684,8 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
, m_NexusGameID(game->nexusGameID())
, m_GameName(game->gameNexusName())
, m_Endorse(false)
{}
{
}
NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
, QString modVersion
+8
View File
@@ -349,6 +349,11 @@ signals:
void nxmEndorsementToggled(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID);
void nxmRequestFailed(QString gameName, int modID, int fileID, QVariant userData, int requestID, QNetworkReply::NetworkError error, const QString &errorString);
public slots:
void setRateMax(const QString &userName, bool isPremium);
void calculateRequests();
private slots:
void requestFinished();
@@ -418,6 +423,9 @@ private:
PluginContainer *m_PluginContainer;
int m_RemainingRequests;
int m_MaxRequests;
};
#endif // NEXUSINTERFACE_H
+1 -2
View File
@@ -252,8 +252,7 @@ void NXMAccessManager::validateFinished()
QString test = jdoc.toJson();
QString name = credentialsData.value("name").toString();
bool premium = credentialsData.value("is_premium?").toBool();
emit credentialsReceived(credentialsData.value("name").toString(),
credentialsData.value("is_premium?").toBool());
emit credentialsReceived(name, premium);
m_ValidateReply->deleteLater();
m_ValidateReply = nullptr;