mirror of
https://github.com/Relintai/rcpp_framework.git
synced 2024-11-14 04:57:21 +01:00
Implemented body caching and cleanups to FileCache.
This commit is contained in:
parent
dc3967c5f4
commit
4e98d05bd5
@ -38,7 +38,7 @@ void Application::handle_request(Request *request) {
|
||||
|
||||
std::string path = request->http_parser->getPath();
|
||||
|
||||
if (FileCache::get_instance()->has_file(path)) {
|
||||
if (FileCache::get_singleton()->wwwroot_has_file(path)) {
|
||||
send_file(path, request);
|
||||
|
||||
return;
|
||||
@ -92,7 +92,7 @@ void Application::send_error(int error_code, Request *request) {
|
||||
}
|
||||
|
||||
void Application::send_file(const std::string &path, Request *request) {
|
||||
std::string fp = FileCache::get_instance()->wwwroot + path;
|
||||
std::string fp = FileCache::get_singleton()->wwwroot + path;
|
||||
|
||||
FILE *f = fopen(fp.c_str(), "rb");
|
||||
|
||||
|
@ -4,25 +4,25 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void FileCache::register_file(const std::string &file_path) {
|
||||
void FileCache::wwwroot_register_file(const std::string &file_path) {
|
||||
registered_files.insert(file_path);
|
||||
}
|
||||
|
||||
void FileCache::deregister_file(const std::string &file_path) {
|
||||
void FileCache::wwwroot_deregister_file(const std::string &file_path) {
|
||||
registered_files.erase(file_path);
|
||||
}
|
||||
|
||||
bool FileCache::has_file(const std::string &file_path) {
|
||||
bool FileCache::wwwroot_has_file(const std::string &file_path) {
|
||||
return registered_files.find(file_path) != registered_files.end();
|
||||
}
|
||||
|
||||
void FileCache::refresh() {
|
||||
void FileCache::wwwroot_refresh_cache() {
|
||||
registered_files.clear();
|
||||
|
||||
evaluate_dir(wwwroot.c_str());
|
||||
wwwroot_evaluate_dir(wwwroot.c_str());
|
||||
}
|
||||
|
||||
void FileCache::evaluate_dir(const char *path) {
|
||||
void FileCache::wwwroot_evaluate_dir(const char *path) {
|
||||
tinydir_dir dir;
|
||||
if (tinydir_open(&dir, path) == -1) {
|
||||
printf("Error opening wwwroot!\n");
|
||||
@ -47,7 +47,7 @@ void FileCache::evaluate_dir(const char *path) {
|
||||
continue;
|
||||
}
|
||||
|
||||
evaluate_dir(file.path);
|
||||
wwwroot_evaluate_dir(file.path);
|
||||
}
|
||||
|
||||
tinydir_next(&dir);
|
||||
@ -56,17 +56,68 @@ void FileCache::evaluate_dir(const char *path) {
|
||||
tinydir_close(&dir);
|
||||
}
|
||||
|
||||
FileCache::FileCache() {
|
||||
_instance = this;
|
||||
bool FileCache::get_cached_body(const std::string &path, std::string *body) {
|
||||
//TODO ERROR MACRO body == null
|
||||
|
||||
//this shouldn't need mutexes
|
||||
|
||||
CacheEntry *e = cache_map[path];
|
||||
|
||||
if (!e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t current_timestamp = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
|
||||
int64_t diff = current_timestamp - e->timestamp;
|
||||
|
||||
if (diff > cache_invalidation_time) {
|
||||
return false;
|
||||
}
|
||||
|
||||
body->append(e->body);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileCache::set_cached_body(const std::string &path, const std::string &body) {
|
||||
cache_mutex.lock();
|
||||
|
||||
CacheEntry *e = cache_map[path];
|
||||
|
||||
if (!e) {
|
||||
e = new CacheEntry();
|
||||
cache_map[path] = e;
|
||||
}
|
||||
|
||||
int64_t current_timestamp = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
|
||||
e->timestamp = current_timestamp;
|
||||
e->body = body;
|
||||
|
||||
cache_mutex.unlock();
|
||||
}
|
||||
|
||||
FileCache::FileCache(bool singleton) {
|
||||
if (singleton) {
|
||||
if (_instance) {
|
||||
printf("FileCache: Filecache instance is set as singleton, but an another FileCache instance is already set up as singleton! Ignoring setting!\n");
|
||||
} else {
|
||||
_instance = this;
|
||||
}
|
||||
}
|
||||
|
||||
cache_invalidation_time = 1;
|
||||
}
|
||||
|
||||
FileCache::~FileCache() {
|
||||
registered_files.clear();
|
||||
|
||||
_instance = nullptr;
|
||||
if (_instance == this)
|
||||
_instance = nullptr;
|
||||
}
|
||||
|
||||
FileCache *FileCache::get_instance() {
|
||||
FileCache *FileCache::get_singleton() {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
|
@ -3,28 +3,48 @@
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
|
||||
class FileCache {
|
||||
public:
|
||||
std::string wwwroot;
|
||||
int cache_invalidation_time;
|
||||
|
||||
//Note: file path should be the url you want to access the file with, inculding lead slash
|
||||
//e.g. http://127.0.0.1/a/b/d.jpg -> /a/b/d.jpg
|
||||
void register_file(const std::string &file_path);
|
||||
void deregister_file(const std::string &file_path);
|
||||
void wwwroot_register_file(const std::string &file_path);
|
||||
void wwwroot_deregister_file(const std::string &file_path);
|
||||
bool wwwroot_has_file(const std::string &file_path);
|
||||
void wwwroot_refresh_cache();
|
||||
void wwwroot_evaluate_dir(const char *path);
|
||||
|
||||
bool has_file(const std::string &file_path);
|
||||
bool get_cached_body(const std::string &path, std::string *body);
|
||||
void set_cached_body(const std::string &path, const std::string &body);
|
||||
|
||||
void refresh();
|
||||
void evaluate_dir(const char *path);
|
||||
|
||||
FileCache();
|
||||
FileCache(bool singleton = false);
|
||||
virtual ~FileCache();
|
||||
|
||||
static FileCache *get_instance();
|
||||
static FileCache *get_singleton();
|
||||
|
||||
std::set<std::string> registered_files;
|
||||
|
||||
protected:
|
||||
|
||||
struct CacheEntry {
|
||||
int64_t timestamp;
|
||||
std::string body;
|
||||
|
||||
CacheEntry() {
|
||||
timestamp = 0;
|
||||
}
|
||||
};
|
||||
|
||||
std::mutex cache_mutex;
|
||||
|
||||
std::map<std::string, CacheEntry *> cache_map;
|
||||
|
||||
private:
|
||||
static FileCache *_instance;
|
||||
};
|
||||
|
4
main.cpp
4
main.cpp
@ -10,9 +10,9 @@
|
||||
#define MAIN_CLASS RDNApplication
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
FileCache *file_cache = new FileCache();
|
||||
FileCache *file_cache = new FileCache(true);
|
||||
file_cache->wwwroot = "./www";
|
||||
file_cache->refresh();
|
||||
file_cache->wwwroot_refresh_cache();
|
||||
|
||||
Application *app = new MAIN_CLASS();
|
||||
|
||||
|
@ -4,16 +4,28 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void RDNApplication::index(Request *request) {
|
||||
//std::string body = "<html>hello world aaaaa </html>";
|
||||
#include "core/file_cache.h"
|
||||
|
||||
std::string body = "<html><script>var blocked = false; document.addEventListener(\"visibilitychange\", function() { if (!blocked && document.hidden) {blocked = true;alert('Blocked once');}});</script></html>";
|
||||
void RDNApplication::index(Request *request) {
|
||||
std::string body;
|
||||
|
||||
if (FileCache::get_singleton()->get_cached_body("index", &body)) {
|
||||
std::string body = "<html>hello world aaaaa </html>";
|
||||
|
||||
request->response->setBody(body);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
body = "<html>hello world aaaaa </html>";
|
||||
|
||||
FileCache::get_singleton()->set_cached_body("index", body);
|
||||
|
||||
request->response->setBody(body);
|
||||
}
|
||||
|
||||
void RDNApplication::session_middleware_func(Request *request) {
|
||||
std::cout << "dddd" << std::endl;
|
||||
std::cout << "dddd" << std::endl;
|
||||
}
|
||||
|
||||
void RDNApplication::setup_routes() {
|
||||
|
Loading…
Reference in New Issue
Block a user