horrific memeory leak in rate limiter

This commit is contained in:
Akash Mozumdar 2019-06-05 20:26:50 -04:00
parent e107eff849
commit b18fe3ddd0
4 changed files with 24 additions and 15 deletions

View File

@ -113,7 +113,7 @@ std::wstring Translate(const std::wstring& text, std::wstring translateFrom, std
// Response formatted as JSON: translation starts with :" and ends with "} // Response formatted as JSON: translation starts with :" and ends with "}
else if (std::wsmatch results; std::regex_search(response.value(), results, std::wregex(L":\"(.+)\"\\}"))) translation = results[1]; else if (std::wsmatch results; std::regex_search(response.value(), results, std::wregex(L":\"(.+)\"\\}"))) translation = results[1];
Escape(translation); Unescape(translation);
return translation; return translation;
} }

View File

@ -159,7 +159,7 @@ bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)
{ {
for (std::wsmatch results; std::regex_search(response.value(), results, std::wregex(L"\\[\"(.*?)\",[n\"]")); response = results.suffix()) for (std::wsmatch results; std::regex_search(response.value(), results, std::wregex(L"\\[\"(.*?)\",[n\"]")); response = results.suffix())
translation += std::wstring(results[1]) + L" "; translation += std::wstring(results[1]) + L" ";
Escape(translation); Unescape(translation);
} }
else else
{ {

View File

@ -24,7 +24,7 @@ inline std::optional<std::wstring> ReceiveHttpRequest(HINTERNET request)
return StringToWideString(data); return StringToWideString(data);
} }
inline void Escape(std::wstring& text) inline void Unescape(std::wstring& text)
{ {
for (int i = 0; i < text.size(); ++i) for (int i = 0; i < text.size(); ++i)
{ {
@ -37,3 +37,24 @@ inline void Escape(std::wstring& text)
} }
} }
} }
class RateLimiter
{
public:
RateLimiter(int tokenCount, int delay) : tokenCount(tokenCount), delay(delay) {}
bool Request()
{
auto tokens = this->tokens.Acquire();
tokens->push_back(GetTickCount());
if (tokens->size() > tokenCount * 5) tokens->erase(tokens->begin(), tokens->begin() + tokenCount * 3);
tokens->erase(std::remove_if(tokens->begin(), tokens->end(), [this](DWORD token) { return GetTickCount() - token > delay; }), tokens->end());
return tokens->size() < tokenCount;
}
const int tokenCount, delay;
private:
Synchronized<std::vector<DWORD>> tokens;
};

View File

@ -2,18 +2,6 @@
#include "common.h" #include "common.h"
class RateLimiter
{
public:
RateLimiter(int requests, int delay) : requestsLeft(requests), delay(delay) {}
bool Request() { CreateTimerQueueTimer(DUMMY, timerQueue, [](void* This, BOOLEAN) { ((RateLimiter*)This)->requestsLeft += 1; }, this, delay, 0, 0); return --requestsLeft > 0; }
int delay;
private:
std::atomic<int> requestsLeft;
AutoHandle<Functor<DeleteTimerQueue>> timerQueue = CreateTimerQueue();
};
inline std::wstring StringToWideString(const std::string& text) inline std::wstring StringToWideString(const std::string& text)
{ {
std::vector<wchar_t> buffer(text.size() + 1); std::vector<wchar_t> buffer(text.size() + 1);