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();
|
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);
|
send_file(path, request);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -92,7 +92,7 @@ void Application::send_error(int error_code, Request *request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Application::send_file(const std::string &path, 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");
|
FILE *f = fopen(fp.c_str(), "rb");
|
||||||
|
|
||||||
|
@ -4,25 +4,25 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#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);
|
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);
|
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();
|
return registered_files.find(file_path) != registered_files.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileCache::refresh() {
|
void FileCache::wwwroot_refresh_cache() {
|
||||||
registered_files.clear();
|
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;
|
tinydir_dir dir;
|
||||||
if (tinydir_open(&dir, path) == -1) {
|
if (tinydir_open(&dir, path) == -1) {
|
||||||
printf("Error opening wwwroot!\n");
|
printf("Error opening wwwroot!\n");
|
||||||
@ -47,7 +47,7 @@ void FileCache::evaluate_dir(const char *path) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
evaluate_dir(file.path);
|
wwwroot_evaluate_dir(file.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
tinydir_next(&dir);
|
tinydir_next(&dir);
|
||||||
@ -56,17 +56,68 @@ void FileCache::evaluate_dir(const char *path) {
|
|||||||
tinydir_close(&dir);
|
tinydir_close(&dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileCache::FileCache() {
|
bool FileCache::get_cached_body(const std::string &path, std::string *body) {
|
||||||
_instance = this;
|
//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() {
|
FileCache::~FileCache() {
|
||||||
registered_files.clear();
|
registered_files.clear();
|
||||||
|
|
||||||
_instance = nullptr;
|
if (_instance == this)
|
||||||
|
_instance = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileCache *FileCache::get_instance() {
|
FileCache *FileCache::get_singleton() {
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,28 +3,48 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <map>
|
||||||
|
#include <chrono>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
class FileCache {
|
class FileCache {
|
||||||
public:
|
public:
|
||||||
std::string wwwroot;
|
std::string wwwroot;
|
||||||
|
int cache_invalidation_time;
|
||||||
|
|
||||||
//Note: file path should be the url you want to access the file with, inculding lead slash
|
//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
|
//e.g. http://127.0.0.1/a/b/d.jpg -> /a/b/d.jpg
|
||||||
void register_file(const std::string &file_path);
|
void wwwroot_register_file(const std::string &file_path);
|
||||||
void deregister_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();
|
FileCache(bool singleton = false);
|
||||||
void evaluate_dir(const char *path);
|
|
||||||
|
|
||||||
FileCache();
|
|
||||||
virtual ~FileCache();
|
virtual ~FileCache();
|
||||||
|
|
||||||
static FileCache *get_instance();
|
static FileCache *get_singleton();
|
||||||
|
|
||||||
std::set<std::string> registered_files;
|
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:
|
private:
|
||||||
static FileCache *_instance;
|
static FileCache *_instance;
|
||||||
};
|
};
|
||||||
|
4
main.cpp
4
main.cpp
@ -10,9 +10,9 @@
|
|||||||
#define MAIN_CLASS RDNApplication
|
#define MAIN_CLASS RDNApplication
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
FileCache *file_cache = new FileCache();
|
FileCache *file_cache = new FileCache(true);
|
||||||
file_cache->wwwroot = "./www";
|
file_cache->wwwroot = "./www";
|
||||||
file_cache->refresh();
|
file_cache->wwwroot_refresh_cache();
|
||||||
|
|
||||||
Application *app = new MAIN_CLASS();
|
Application *app = new MAIN_CLASS();
|
||||||
|
|
||||||
|
@ -4,16 +4,28 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
void RDNApplication::index(Request *request) {
|
#include "core/file_cache.h"
|
||||||
//std::string body = "<html>hello world aaaaa </html>";
|
|
||||||
|
|
||||||
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);
|
request->response->setBody(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RDNApplication::session_middleware_func(Request *request) {
|
void RDNApplication::session_middleware_func(Request *request) {
|
||||||
std::cout << "dddd" << std::endl;
|
std::cout << "dddd" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RDNApplication::setup_routes() {
|
void RDNApplication::setup_routes() {
|
||||||
|
Loading…
Reference in New Issue
Block a user