forked from OpenGamers/abaddon
allow limiting concurrent http requests
add Semaphore update SettingsManager a little
This commit is contained in:
parent
bbe36a8246
commit
43f87b4bca
@ -85,7 +85,7 @@ int Abaddon::StartGTK() {
|
||||
}
|
||||
|
||||
void Abaddon::LoadFromSettings() {
|
||||
std::string token = m_settings.GetSetting("discord", "token");
|
||||
std::string token = m_settings.GetSettingString("discord", "token");
|
||||
if (token.size()) {
|
||||
m_discord_token = token;
|
||||
m_discord.UpdateToken(m_discord_token);
|
||||
@ -150,6 +150,10 @@ void Abaddon::DiscordOnGuildDelete(Snowflake guild_id) {
|
||||
m_main_window->UpdateChannelListing();
|
||||
}
|
||||
|
||||
const SettingsManager &Abaddon::GetSettings() const {
|
||||
return m_settings;
|
||||
}
|
||||
|
||||
void Abaddon::ActionConnect() {
|
||||
if (!m_discord.IsStarted())
|
||||
StartDiscord();
|
||||
|
@ -61,6 +61,8 @@ public:
|
||||
void DiscordOnGuildCreate(Snowflake guild_id);
|
||||
void DiscordOnGuildDelete(Snowflake guild_id);
|
||||
|
||||
const SettingsManager &GetSettings() const;
|
||||
|
||||
private:
|
||||
DiscordClient m_discord;
|
||||
std::string m_discord_token;
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include "abaddon.hpp"
|
||||
#include "filecache.hpp"
|
||||
|
||||
constexpr static const int MaxConcurrentCacheHTTP = 10;
|
||||
|
||||
Cache::Cache() {
|
||||
m_tmp_path = std::filesystem::temp_directory_path() / "abaddon-cache";
|
||||
std::filesystem::create_directories(m_tmp_path);
|
||||
@ -29,16 +32,25 @@ void Cache::RespondFromPath(std::filesystem::path path, callback_type cb) {
|
||||
void Cache::GetFileFromURL(std::string url, callback_type cb) {
|
||||
auto cache_path = m_tmp_path / SanitizeString(url);
|
||||
if (std::filesystem::exists(cache_path)) {
|
||||
m_futures.push_back(std::async(std::launch::async, [this, cache_path, cb]() {
|
||||
RespondFromPath(cache_path, cb); }));
|
||||
m_futures.push_back(std::async(std::launch::async, [this, cache_path, cb]() { RespondFromPath(cache_path, cb); }));
|
||||
return;
|
||||
}
|
||||
|
||||
// needs to be initialized like this or else ::Get() is called recursively
|
||||
if (!m_semaphore)
|
||||
m_semaphore = std::make_unique<Semaphore>(Abaddon::Get().GetSettings().GetSettingInt("http", "concurrent", MaxConcurrentCacheHTTP));
|
||||
|
||||
if (m_callbacks.find(url) != m_callbacks.end()) {
|
||||
m_callbacks[url].push_back(cb);
|
||||
} else {
|
||||
m_futures.push_back(cpr::GetCallback(std::bind(&Cache::OnResponse, this, std::placeholders::_1), cpr::Url { url }));
|
||||
m_callbacks[url].push_back(cb);
|
||||
auto future = std::async(std::launch::async, [this, url]() {
|
||||
m_semaphore->wait();
|
||||
const auto &r = cpr::Get(cpr::Url { url });
|
||||
m_semaphore->notify();
|
||||
OnResponse(r);
|
||||
});
|
||||
m_futures.push_back(std::move(future));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include "util.hpp"
|
||||
|
||||
// todo throttle requests and keep track of active requests to stop redundant requests
|
||||
|
||||
@ -23,6 +24,8 @@ private:
|
||||
void RespondFromPath(std::filesystem::path path, callback_type cb);
|
||||
void OnResponse(const cpr::Response &r);
|
||||
|
||||
std::unique_ptr<Semaphore> m_semaphore;
|
||||
|
||||
std::unordered_map<std::string, std::vector<callback_type>> m_callbacks;
|
||||
std::vector<std::future<void>> m_futures;
|
||||
std::filesystem::path m_tmp_path;
|
||||
|
@ -14,12 +14,12 @@ SettingsManager::SettingsManager(std::string filename)
|
||||
m_ok = rc == SI_OK;
|
||||
}
|
||||
|
||||
std::string SettingsManager::GetSetting(std::string section, std::string key, std::string fallback) {
|
||||
std::string SettingsManager::GetSettingString(std::string section, std::string key, std::string fallback) const {
|
||||
return m_ini.GetValue(section.c_str(), key.c_str(), fallback.c_str());
|
||||
}
|
||||
|
||||
void SettingsManager::SetSetting(std::string section, std::string key, std::string value) {
|
||||
m_ini.SetValue(section.c_str(), key.c_str(), value.c_str());
|
||||
int SettingsManager::GetSettingInt(std::string section, std::string key, int fallback) const {
|
||||
return std::stoul(GetSettingString(section, key, std::to_string(fallback)));
|
||||
}
|
||||
|
||||
bool SettingsManager::IsValid() const {
|
||||
|
14
settings.hpp
14
settings.hpp
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <SimpleIni.h>
|
||||
|
||||
class SettingsManager {
|
||||
@ -7,8 +8,17 @@ public:
|
||||
SettingsManager(std::string filename);
|
||||
|
||||
void Close();
|
||||
std::string GetSetting(std::string section, std::string key, std::string fallback = "");
|
||||
void SetSetting(std::string section, std::string key, std::string value);
|
||||
std::string GetSettingString(std::string section, std::string key, std::string fallback = "") const;
|
||||
int GetSettingInt(std::string section, std::string key, int fallback) const;
|
||||
|
||||
template<typename T>
|
||||
void SetSetting(std::string section, std::string key, T value) {
|
||||
static_assert(std::is_convertible<T, std::string>::value);
|
||||
if constexpr (std::is_same<T, std::string>::value)
|
||||
m_ini.SetValue(section.c_str(), key.c_str(), value.c_str());
|
||||
else
|
||||
m_ini.SetValue(section.c_str(), key.c_str(), std::to_string(value).c_str());
|
||||
}
|
||||
bool IsValid() const;
|
||||
|
||||
private:
|
||||
|
27
util.hpp
27
util.hpp
@ -8,7 +8,34 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <regex>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
|
||||
class Semaphore {
|
||||
public:
|
||||
Semaphore(int count = 0)
|
||||
: m_count(count) {}
|
||||
|
||||
inline void notify() {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
m_count++;
|
||||
lock.unlock();
|
||||
m_cv.notify_one();
|
||||
}
|
||||
|
||||
inline void wait() {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
while (m_count == 0)
|
||||
m_cv.wait(lock);
|
||||
m_count--;
|
||||
}
|
||||
|
||||
private:
|
||||
std::mutex m_mutex;
|
||||
std::condition_variable m_cv;
|
||||
int m_count;
|
||||
};
|
||||
// gtkmm doesnt seem to work
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
Loading…
Reference in New Issue
Block a user