From 21e37e1ca97871601ca64c06b0791d709b04c403 Mon Sep 17 00:00:00 2001 From: David Fairbrother <DavidFair@users.noreply.github.com> Date: Wed, 20 Jun 2018 17:07:32 +0100 Subject: [PATCH] Re #0 Add Project recovery to config --- .../Properties/Mantid.properties.template | 3 ++ MantidPlot/src/ProjectRecoveryThread.cpp | 51 +++++++++++++++++-- MantidPlot/src/ProjectRecoveryThread.h | 14 +++++ 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/Framework/Properties/Mantid.properties.template b/Framework/Properties/Mantid.properties.template index d77b4e226d3..44461931420 100644 --- a/Framework/Properties/Mantid.properties.template +++ b/Framework/Properties/Mantid.properties.template @@ -252,3 +252,6 @@ cluster.submission=Off # Used to stop a catalog asynchronous algorithm after the timeout period catalog.timeout.value=30 + +# Indicates if project recovery should automatically save in the background +projectRecovery.enabled=true \ No newline at end of file diff --git a/MantidPlot/src/ProjectRecoveryThread.cpp b/MantidPlot/src/ProjectRecoveryThread.cpp index 0fb437478d8..7bcde944874 100644 --- a/MantidPlot/src/ProjectRecoveryThread.cpp +++ b/MantidPlot/src/ProjectRecoveryThread.cpp @@ -6,8 +6,10 @@ #include "globals.h" #include "MantidAPI/FileProperty.h" +#include "MantidKernel/ConfigService.h" #include "MantidKernel/Logger.h" +#include "Poco/NObserver.h" #include "Poco/Path.h" #include "qmetaobject.h" @@ -18,7 +20,17 @@ #include <thread> namespace { +Mantid::Kernel::Logger g_log("Project Recovery Thread"); const std::chrono::seconds TIME_BETWEEN_SAVING = std::chrono::seconds(30); +const std::string SAVING_ENABLED_CONFIG_KEY = "projectRecovery.enabled"; + +bool isRecoveryEnabled() { + std::string isEnabled; + int valueIsGood = Mantid::Kernel::ConfigService::Instance().getValue<std::string>( + SAVING_ENABLED_CONFIG_KEY, isEnabled); + + return (valueIsGood == 1) && isEnabled.find("true") != std::string::npos; +} std::string getOutputPath() { static bool isInitalised = false; @@ -35,16 +47,19 @@ std::string getOutputPath() { std::string getOutputProjectName() { return "recovery.project"; } -Mantid::Kernel::Logger g_log("Project Recovery Thread"); } // namespace namespace MantidQt { namespace API { ProjectRecoveryThread::ProjectRecoveryThread(ApplicationWindow *windowHandle) - : m_windowPtr(windowHandle), m_backgroundSavingThread(), - m_stopBackgroundThread(true) { - startProjectSaving(); + : m_backgroundSavingThread(), m_stopBackgroundThread(true), + m_configKeyObserver(*this, &ProjectRecoveryThread::configKeyChanged), + m_windowPtr(windowHandle) { + + if (isRecoveryEnabled()) { + startProjectSaving(); + } } ProjectRecoveryThread::~ProjectRecoveryThread() { stopProjectSaving(); } @@ -52,7 +67,20 @@ ProjectRecoveryThread::~ProjectRecoveryThread() { stopProjectSaving(); } std::thread ProjectRecoveryThread::createBackgroundThread() { // Using a lambda helps the compiler deduce the this pointer // otherwise the resolution is ambiguous - return std::thread([this] { projectSavingThread(); }); + return std::thread([this] { projectSavingThreadWrapper(); }); +} + +void ProjectRecoveryThread::configKeyChanged( + Mantid::Kernel::ConfigValChangeNotification_ptr notif) { + if (notif->key() != (SAVING_ENABLED_CONFIG_KEY)) { + return; + } + + if (notif->curValue() == "True") { + startProjectSaving(); + } else { + stopProjectSaving(); + } } void ProjectRecoveryThread::startProjectSaving() { @@ -80,6 +108,19 @@ void ProjectRecoveryThread::stopProjectSaving() { } } +void ProjectRecoveryThread::projectSavingThreadWrapper() { + try { + projectSavingThread(); + } catch (std::exception const &e) { + std::string preamble("Project recovery has stopped. Please report" + " this to the development team.\nException:\n"); + g_log.warning(preamble + e.what()); + } catch (...) { + g_log.warning("Project recovery has stopped. Please report" + " this to the development team."); + } +} + void ProjectRecoveryThread::projectSavingThread() { while (!m_stopBackgroundThread) { std::unique_lock<std::mutex> lock(m_notifierMutex); diff --git a/MantidPlot/src/ProjectRecoveryThread.h b/MantidPlot/src/ProjectRecoveryThread.h index 520a1b53622..3669194bfe7 100644 --- a/MantidPlot/src/ProjectRecoveryThread.h +++ b/MantidPlot/src/ProjectRecoveryThread.h @@ -1,6 +1,10 @@ #ifndef PROJECT_RECOVERY_THREAD_H_ #define PROJECT_RECOVERY_THREAD_H_ +#include "MantidKernel/ConfigService.h" + +#include <Poco/NObserver.h> + #include <chrono> #include <condition_variable> #include <mutex> @@ -55,12 +59,17 @@ private: /// Captures the current object in the background thread std::thread createBackgroundThread(); + /// Triggers when the config key is updated to a new value + void configKeyChanged(Mantid::Kernel::ConfigValChangeNotification_ptr notif); + /// Loads a project recovery file back into Mantid void loadOpenWindows(const std::string &projectFolder); /// Saves a project recovery file in Mantid void saveOpenWindows(const std::string &projectDestFolder); /// Saves the current workspace's histories from Mantid void saveWsHistories(const std::string &projectDestFile); + /// Wraps the thread in a try catch to log any failures + void projectSavingThreadWrapper(); /// Main body of saving thread void projectSavingThread(); @@ -74,6 +83,11 @@ private: /// Atomic to detect when the thread should fire or exit std::condition_variable m_threadNotifier; + /// Config observer to monitor the key + Poco::NObserver<ProjectRecoveryThread, + Mantid::Kernel::ConfigValChangeNotification> + m_configKeyObserver; + /// Pointer to main GUI window ApplicationWindow *m_windowPtr; }; -- GitLab