Commit 5111f73da157233df0c8ed17ec89b666aef8f30f
1 parent
cd429cb7
Reduce blocking of threads when saving state
Showing
3 changed files
with
34 additions
and
2 deletions
mainapp.cpp
| @@ -210,7 +210,7 @@ MainApp::MainApp(const std::string &configFilePath) : | @@ -210,7 +210,7 @@ MainApp::MainApp(const std::string &configFilePath) : | ||
| 210 | subscriptionStore->loadSessionsAndSubscriptions(settings->getSessionsDBFile()); | 210 | subscriptionStore->loadSessionsAndSubscriptions(settings->getSessionsDBFile()); |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | - auto fSaveState = std::bind(&MainApp::saveState, this); | 213 | + auto fSaveState = std::bind(&MainApp::saveStateInThread, this); |
| 214 | timer.addCallback(fSaveState, 900000, "Save state."); | 214 | timer.addCallback(fSaveState, 900000, "Save state."); |
| 215 | } | 215 | } |
| 216 | 216 | ||
| @@ -355,8 +355,31 @@ void MainApp::queuePublishStatsOnDollarTopic() | @@ -355,8 +355,31 @@ void MainApp::queuePublishStatsOnDollarTopic() | ||
| 355 | } | 355 | } |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | +/** | ||
| 359 | + * @brief MainApp::saveStateInThread starts a thread for disk IO, because file IO is not async. | ||
| 360 | + */ | ||
| 361 | +void MainApp::saveStateInThread() | ||
| 362 | +{ | ||
| 363 | + // Prevent queueing it again when it's still running. | ||
| 364 | + std::unique_lock<std::mutex> locker(saveStateMutex, std::try_to_lock); | ||
| 365 | + if (!locker.owns_lock()) | ||
| 366 | + return; | ||
| 367 | + | ||
| 368 | + // Join previous instances. | ||
| 369 | + if (saveStateThread.joinable()) | ||
| 370 | + saveStateThread.join(); | ||
| 371 | + | ||
| 372 | + auto f = std::bind(&MainApp::saveState, this); | ||
| 373 | + saveStateThread = std::thread(f); | ||
| 374 | + | ||
| 375 | + pthread_t native = saveStateThread.native_handle(); | ||
| 376 | + pthread_setname_np(native, "SaveState"); | ||
| 377 | +} | ||
| 378 | + | ||
| 358 | void MainApp::saveState() | 379 | void MainApp::saveState() |
| 359 | { | 380 | { |
| 381 | + std::lock_guard<std::mutex> lg(saveStateMutex); | ||
| 382 | + | ||
| 360 | try | 383 | try |
| 361 | { | 384 | { |
| 362 | if (!settings->storageDir.empty()) | 385 | if (!settings->storageDir.empty()) |
| @@ -366,6 +389,8 @@ void MainApp::saveState() | @@ -366,6 +389,8 @@ void MainApp::saveState() | ||
| 366 | 389 | ||
| 367 | const std::string sessionsDBPath = settings->getSessionsDBFile(); | 390 | const std::string sessionsDBPath = settings->getSessionsDBFile(); |
| 368 | subscriptionStore->saveSessionsAndSubscriptions(sessionsDBPath); | 391 | subscriptionStore->saveSessionsAndSubscriptions(sessionsDBPath); |
| 392 | + | ||
| 393 | + logger->logf(LOG_INFO, "Saving states done"); | ||
| 369 | } | 394 | } |
| 370 | } | 395 | } |
| 371 | catch(std::exception &ex) | 396 | catch(std::exception &ex) |
| @@ -669,6 +694,9 @@ void MainApp::start() | @@ -669,6 +694,9 @@ void MainApp::start() | ||
| 669 | } | 694 | } |
| 670 | 695 | ||
| 671 | saveState(); | 696 | saveState(); |
| 697 | + | ||
| 698 | + if (saveStateThread.joinable()) | ||
| 699 | + saveStateThread.join(); | ||
| 672 | } | 700 | } |
| 673 | 701 | ||
| 674 | void MainApp::quit() | 702 | void MainApp::quit() |
mainapp.h
| @@ -71,6 +71,9 @@ class MainApp | @@ -71,6 +71,9 @@ class MainApp | ||
| 71 | 71 | ||
| 72 | Logger *logger = Logger::getInstance(); | 72 | Logger *logger = Logger::getInstance(); |
| 73 | 73 | ||
| 74 | + std::thread saveStateThread; | ||
| 75 | + std::mutex saveStateMutex; | ||
| 76 | + | ||
| 74 | void setlimits(); | 77 | void setlimits(); |
| 75 | void loadConfig(); | 78 | void loadConfig(); |
| 76 | void reloadConfig(); | 79 | void reloadConfig(); |
| @@ -84,6 +87,7 @@ class MainApp | @@ -84,6 +87,7 @@ class MainApp | ||
| 84 | void setFuzzFile(const std::string &fuzzFilePath); | 87 | void setFuzzFile(const std::string &fuzzFilePath); |
| 85 | void queuePublishStatsOnDollarTopic(); | 88 | void queuePublishStatsOnDollarTopic(); |
| 86 | void saveState(); | 89 | void saveState(); |
| 90 | + void saveStateInThread(); | ||
| 87 | 91 | ||
| 88 | MainApp(const std::string &configFilePath); | 92 | MainApp(const std::string &configFilePath); |
| 89 | public: | 93 | public: |
subscriptionstore.cpp
| @@ -634,7 +634,7 @@ void SubscriptionStore::saveSessionsAndSubscriptions(const std::string &filePath | @@ -634,7 +634,7 @@ void SubscriptionStore::saveSessionsAndSubscriptions(const std::string &filePath | ||
| 634 | logger->logf(LOG_INFO, "Saving sessions and subscriptions to '%s'", filePath.c_str()); | 634 | logger->logf(LOG_INFO, "Saving sessions and subscriptions to '%s'", filePath.c_str()); |
| 635 | 635 | ||
| 636 | RWLockGuard lock_guard(&subscriptionsRwlock); | 636 | RWLockGuard lock_guard(&subscriptionsRwlock); |
| 637 | - lock_guard.wrlock(); | 637 | + lock_guard.rdlock(); |
| 638 | 638 | ||
| 639 | // First copy the sessions... | 639 | // First copy the sessions... |
| 640 | 640 |