Reintroduce cache file as it is still required for "lastUpdate" for DBs

Maybe it makes more sense to use LMDB for this as well. On the other hand
it is an easy way of keeping the remaining state persistent.
This commit is contained in:
Martchus 2022-02-20 20:17:42 +01:00
parent 9c4f0277bd
commit 8ea2f5fd62
4 changed files with 58 additions and 0 deletions

View File

@ -71,6 +71,7 @@ set(META_APP_DESCRIPTION "Library for managing custom Arch Linux repositories")
set(META_VERSION_MAJOR 0)
set(META_VERSION_MINOR 0)
set(META_VERSION_PATCH 1)
set(META_VERSION_CACHE 11)
set(LINK_TESTS_AGAINST_APP_TARGET ON)
# find c++utilities
@ -117,6 +118,9 @@ list(APPEND PUBLIC_LIBRARIES pthread)
# apply basic configuration
include(BasicConfig)
# add cache version to config header
string(APPEND META_CUSTOM_CONFIG "#define ${META_PROJECT_VARNAME}_CACHE_VERSION \"${META_VERSION_CACHE}\"\n")
# trigger code generator for tests because the tests already contain structs to be (de)serialized
include(ReflectionGenerator)
add_reflection_generator_invocation(

View File

@ -41,6 +41,12 @@ void ReloadDatabase::run()
auto session
= WebClient::DatabaseQuerySession::create(m_setup.building.ioContext, [this](WebClient::DatabaseQuerySession::ContainerType &&failedDbs) {
// save state for "lastUpdate" timestamps
auto configReadLock2 = m_setup.config.lockToRead();
m_setup.saveState();
configReadLock2.unlock();
// conclude build action
if (!m_preparationFailures.empty()) {
mergeSecondVectorIntoFirstVector(failedDbs, m_preparationFailures);
}

View File

@ -555,8 +555,32 @@ void ServiceSetup::printDatabases()
cerr << Phrases::SubMessage << "AUR (" << config.aur.packageCount() << " packages cached)" << Phrases::End;
}
std::string_view ServiceSetup::cacheFilePath() const
{
return "cache-v" LIBREPOMGR_CACHE_VERSION ".bin";
}
void ServiceSetup::restoreState()
{
// restore configuration and maybe build actions from JSON file
const auto cacheFilePath = this->cacheFilePath();
auto size = std::size_t(0);
try {
auto cacheFile = std::fstream();
cacheFile.exceptions(std::ios_base::failbit | std::ios_base::badbit);
cacheFile.open(cacheFilePath.data(), std::ios_base::in | std::ios_base::binary);
auto deserializer = ReflectiveRapidJSON::BinaryReflector::BinaryDeserializer(&cacheFile);
deserializer.read(config);
size = static_cast<std::uint64_t>(cacheFile.tellg());
cacheFile.close();
std::cerr << Phrases::SuccessMessage << "Restored cache file \"" << cacheFilePath << "\", " << dataSizeToString(size) << Phrases::EndFlush;
} catch (const ConversionException &) {
std::cerr << Phrases::WarningMessage << "A conversion error occurred when restoring cache file \"" << cacheFilePath << "\"."
<< Phrases::EndFlush;
} catch (const ios_base::failure &) {
std::cerr << Phrases::WarningMessage << "An IO error occurred when restoring cache file \"" << cacheFilePath << "\"." << Phrases::EndFlush;
}
// open LMDB storage
cout << Phrases::InfoMessage << "Opening config LMDB file: " << dbPath << " (max DBs: " << maxDbs << ')' << Phrases::EndFlush;
config.initStorage(dbPath.data(), maxDbs);
@ -580,6 +604,26 @@ void ServiceSetup::restoreState()
});
}
std::size_t ServiceSetup::saveState()
{
// write cache file to be able to restore the service state when restarting the service efficiently
const auto cacheFilePath = this->cacheFilePath();
auto size = std::size_t(0);
try {
auto cacheFile = std::fstream();
cacheFile.exceptions(std::ios_base::failbit | std::ios_base::badbit);
cacheFile.open(cacheFilePath.data(), std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
auto serializer = ReflectiveRapidJSON::BinaryReflector::BinarySerializer(&cacheFile);
serializer.write(config);
size = static_cast<std::uint64_t>(cacheFile.tellp());
cacheFile.close();
std::cerr << Phrases::SuccessMessage << "Wrote cache file \"" << cacheFilePath << "\", " << dataSizeToString(size) << Phrases::EndFlush;
} catch (const ios_base::failure &) {
std::cerr << Phrases::WarningMessage << "An IO error occurred when dumping the cache file \"" << cacheFilePath << "\"." << Phrases::EndFlush;
}
return size;
}
void ServiceSetup::initStorage()
{
restoreState();
@ -627,6 +671,8 @@ void ServiceSetup::run()
#endif
}
saveState();
building.forEachBuildAction([](LibPkg::StorageID, BuildAction &buildAction, bool &save) {
if (buildAction.isExecuting()) {
buildAction.status = BuildActionStatus::Finished;

View File

@ -49,7 +49,9 @@ struct LIBREPOMGR_EXPORT ServiceSetup : public LibPkg::Lockable {
void loadConfigFiles(bool doFirstTimeSetup);
void printDatabases();
std::string_view cacheFilePath() const;
void restoreState();
std::size_t saveState();
void initStorage();
void run();
ServiceStatus computeStatus() const;