#include "CacheManager.h" #include #include #include #include #include #include CacheManager::CacheManager(const char* cache_path) : CacheManager(std::string(cache_path)) { } CacheManager::CacheManager(std::string cache_path) { this->cache_path = cache_path; this->verify_cache(); } CacheManager::~CacheManager() { for (std::fstream* file : this->files) { if (file != nullptr) { file->close(); delete file; file = nullptr; } } } void CacheManager::verify_cache() { if (!std::filesystem::is_directory(this->cache_path)) this->init_cache(); this->update_cache(); } void CacheManager::init_cache() { std::filesystem::create_directory(this->cache_path); this->update_cache(); } void CacheManager::update_cache() { std::fstream& date = *cache_get("date"); this->age = std::time(nullptr); date << this->age; date.close(); } void CacheManager::retry(std::string label, bool check_pre, std::function action, std::function retry_if) { for (unsigned int i = 0; i < max_tries; i++) { if (check_pre && retry_if() == false) return; action(); std::this_thread::sleep_for(std::chrono::milliseconds(1)); if (!check_pre && retry_if() == false) return; } std::cout << "retry " << label << " failed after " << max_tries << " tries" << std::endl; } std::fstream* CacheManager::cache_get(const char* filename) { std::filesystem::path fixed_path = prefix_cache_path(filename); // fix duplicate slashes and add prefix retry_if("mkdir", [&] { std::filesystem::create_directories(fixed_path.parent_path()); // make sure folder exists }, [&] { return !std::filesystem::exists(fixed_path.parent_path()); }); retry_if("touch file", [&] { std::fstream(fixed_path, std::ios::trunc | std::ios::out).close(); // touch file }, [&] { return !std::filesystem::exists(fixed_path); }); std::fstream* file = nullptr; retry_while("get file handle", [&] { delete file; file = new std::fstream(fixed_path.c_str(), std::ios::out | std::ios::in); // open file }, [&] { return !file->is_open(); }); this->files.push_back(file); // add file pointer (for closing all files on exit) return file; } bool CacheManager::cache_exists(const char* filename) { return std::filesystem::exists(prefix_cache_path(filename)); } std::string CacheManager::prefix_cache_path(const char* filename) { return this->cache_path + "/" + std::string(filename); }