Add option to use cached results

The cache will remain valid for 10s before it is refreshed with a "real"
Get / Post / Patch call.
This commit is contained in:
WarmUpTill 2023-10-11 12:26:18 +02:00 committed by WarmUpTill
parent 9ac9171206
commit 6cf1073a3c
2 changed files with 128 additions and 0 deletions

View File

@ -4,6 +4,58 @@
namespace advss {
static constexpr std::string_view clientID = "ds5tt4ogliifsqc04mz3d3etnck3e5";
static const int cacheTimeoutSeconds = 10;
class Args {
public:
Args(const std::string &uri, const std::string &path,
const std::string &data, httplib::Params params,
httplib::Headers headers)
: _uri(uri),
_path(path),
_data(data),
_params(params),
_headers(headers)
{
}
bool operator<(const Args &other) const
{
bool ret = true;
ret = ret && _uri < other._uri;
ret = ret && _path < other._path;
ret = ret && _params < other._params;
ret = ret && _data < other._data;
ret = ret && _headers < other._headers;
return ret;
}
private:
std::string _uri;
std::string _path;
std::string _data;
httplib::Params _params;
httplib::Headers _headers;
};
struct CacheEntry {
RequestResult result;
std::chrono::system_clock::time_point cacheTime =
std::chrono::system_clock::now();
};
static bool chacheIsTooOld(const CacheEntry &cache)
{
auto currentTime = std::chrono::system_clock::now();
auto diff = currentTime - cache.cacheTime;
return diff >= std::chrono::seconds(cacheTimeoutSeconds);
}
static bool cacheIsValid(const std::map<Args, CacheEntry> &cache,
const Args &args)
{
auto it = cache.find(args);
return it != cache.end() && !chacheIsTooOld(it->second);
}
static httplib::Headers getTokenRequestHeaders(const TwitchToken &token)
{
@ -37,6 +89,25 @@ RequestResult SendGetRequest(const std::string &uri, const std::string &path,
return result;
}
RequestResult SendGetRequest(const std::string &uri, const std::string &path,
const TwitchToken &token,
const httplib::Params &params, bool useCache)
{
static std::map<Args, CacheEntry> cache;
static std::mutex mtx;
std::lock_guard<std::mutex> lock(mtx);
auto headers = getTokenRequestHeaders(token);
Args args(uri, path, "", params, headers);
if (useCache && cacheIsValid(cache, args)) {
auto it = cache.find(args);
return it->second.result;
}
auto result = SendGetRequest(uri, path, token, params);
cache[args] = {result};
return result;
}
RequestResult SendPostRequest(const std::string &uri, const std::string &path,
const TwitchToken &token, const OBSData &data)
{
@ -62,6 +133,26 @@ RequestResult SendPostRequest(const std::string &uri, const std::string &path,
return result;
}
RequestResult SendPostRequest(const std::string &uri, const std::string &path,
const TwitchToken &token, const OBSData &data,
bool useCache)
{
static std::map<Args, CacheEntry> cache;
static std::mutex mtx;
std::lock_guard<std::mutex> lock(mtx);
auto headers = getTokenRequestHeaders(token);
auto jsonCstr = obs_data_get_json(data);
Args args(uri, path, jsonCstr ? jsonCstr : "", {}, headers);
if (useCache && cacheIsValid(cache, args)) {
auto it = cache.find(args);
return it->second.result;
}
auto result = SendPostRequest(uri, path, token, data);
cache[args] = {result};
return result;
}
RequestResult SendPatchRequest(const std::string &uri, const std::string &path,
const TwitchToken &token, const OBSData &data)
{
@ -87,6 +178,26 @@ RequestResult SendPatchRequest(const std::string &uri, const std::string &path,
return result;
}
RequestResult SendPatchRequest(const std::string &uri, const std::string &path,
const TwitchToken &token, const OBSData &data,
bool useCache)
{
static std::map<Args, CacheEntry> cache;
static std::mutex mtx;
std::lock_guard<std::mutex> lock(mtx);
auto headers = getTokenRequestHeaders(token);
auto jsonCstr = obs_data_get_json(data);
Args args(uri, path, jsonCstr ? jsonCstr : "", {}, headers);
if (useCache && cacheIsValid(cache, args)) {
auto it = cache.find(args);
return it->second.result;
}
auto result = SendPatchRequest(uri, path, token, data);
cache[args] = {result};
return result;
}
const char *GetClientID()
{
return clientID.data();

View File

@ -2,6 +2,7 @@
#include <httplib.h>
#include <obs.hpp>
#include <string>
#include <chrono>
namespace advss {
@ -12,6 +13,8 @@ struct RequestResult {
OBSData data = nullptr;
};
// These functions do *not* use or create RequestResult cache entries
RequestResult SendGetRequest(const std::string &uri, const std::string &path,
const TwitchToken &token,
const httplib::Params & = {});
@ -19,6 +22,20 @@ RequestResult SendPostRequest(const std::string &uri, const std::string &path,
const TwitchToken &token, const OBSData &data);
RequestResult SendPatchRequest(const std::string &uri, const std::string &path,
const TwitchToken &token, const OBSData &data);
// These functions will cache the RequestResult for 10s
// Note that the cache will be reported as a "memory leak" on OBS shutdown
RequestResult SendGetRequest(const std::string &uri, const std::string &path,
const TwitchToken &token, const httplib::Params &,
bool useCache);
RequestResult SendPostRequest(const std::string &uri, const std::string &path,
const TwitchToken &token, const OBSData &data,
bool useCache);
RequestResult SendPatchRequest(const std::string &uri, const std::string &path,
const TwitchToken &token, const OBSData &data,
bool useCache);
const char *GetClientID();
} // namespace advss