Rate limit outgoing JOIN messages (#3115)

Co-authored-by: Rasmus Karlsson <rasmus.karlsson@pajlada.com>
Co-authored-by: Tal Neoran <talneoran@gmail.com>
This commit is contained in:
Paweł
2021-08-04 23:18:34 +02:00
committed by GitHub
parent 0c5abb8149
commit de4f6a9d51
9 changed files with 160 additions and 3 deletions
+45
View File
@@ -0,0 +1,45 @@
#include "RatelimitBucket.hpp"
#include <QTimer>
namespace chatterino {
RatelimitBucket::RatelimitBucket(int budget, int cooldown,
std::function<void(QString)> callback,
QObject *parent)
: QObject(parent)
, budget_(budget)
, cooldown_(cooldown)
, callback_(callback)
{
}
void RatelimitBucket::send(QString channel)
{
this->queue_.append(channel);
if (this->budget_ > 0)
{
this->handleOne();
}
}
void RatelimitBucket::handleOne()
{
if (queue_.isEmpty())
{
return;
}
auto item = queue_.takeFirst();
this->budget_--;
callback_(item);
QTimer::singleShot(cooldown_, this, [this] {
this->budget_++;
this->handleOne();
});
}
} // namespace chatterino
+40
View File
@@ -0,0 +1,40 @@
#pragma once
#include <QList>
#include <QObject>
#include <QString>
namespace chatterino {
class RatelimitBucket : public QObject
{
public:
RatelimitBucket(int budget, int cooldown,
std::function<void(QString)> callback, QObject *parent);
void send(QString channel);
private:
/**
* @brief budget_ denotes the amount of calls that can be handled before we need to wait for the cooldown
**/
int budget_;
/**
* @brief This is the amount of time in milliseconds it takes for one used up budget to be put back into the bucket for use elsewhere
**/
const int cooldown_;
std::function<void(QString)> callback_;
QList<QString> queue_;
/**
* @brief Run the callback on one entry in the queue.
*
* This will start a timer that runs after cooldown_ milliseconds that
* gives back one "token" to the bucket and calls handleOne again.
**/
void handleOne();
};
} // namespace chatterino