Commit 6c6d959a authored by Nick Draper's avatar Nick Draper
Browse files

Add a 5 second delay after completion of the algorithm before deletion

This is all handled through a isReadyForGarbageCollection() method on Algorithm.
This can be overloaded in specific algorithms if needed.
parent 146181c5
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "MantidAPI/DllConfig.h" #include "MantidAPI/DllConfig.h"
#include "MantidAPI/IAlgorithm.h" #include "MantidAPI/IAlgorithm.h"
#include "MantidAPI/IndexTypeProperty.h" #include "MantidAPI/IndexTypeProperty.h"
#include "MantidKernel/DateAndTime.h"
#include "MantidKernel/IValidator.h" #include "MantidKernel/IValidator.h"
#include "MantidKernel/PropertyManagerOwner.h" #include "MantidKernel/PropertyManagerOwner.h"
...@@ -226,6 +227,7 @@ public: ...@@ -226,6 +227,7 @@ public:
bool isInitialized() const override; bool isInitialized() const override;
bool isExecuted() const override; bool isExecuted() const override;
bool isRunning() const override; bool isRunning() const override;
bool isReadyForGarbageCollection() const override;
using Kernel::PropertyManagerOwner::getProperty; using Kernel::PropertyManagerOwner::getProperty;
...@@ -504,6 +506,9 @@ private: ...@@ -504,6 +506,9 @@ private:
/// (MPI) communicator used when executing the algorithm. /// (MPI) communicator used when executing the algorithm.
std::unique_ptr<Parallel::Communicator> m_communicator; std::unique_ptr<Parallel::Communicator> m_communicator;
/// The earliest this class should be considered for garbage collection
Mantid::Types::Core::DateAndTime m_gcTime;
}; };
/// Typedef for a shared pointer to an Algorithm /// Typedef for a shared pointer to an Algorithm
......
...@@ -132,6 +132,9 @@ public: ...@@ -132,6 +132,9 @@ public:
/// True if the algorithm is running. /// True if the algorithm is running.
virtual bool isRunning() const = 0; virtual bool isRunning() const = 0;
/// True if the algorithm is ready for garbage collection.
virtual bool isReadyForGarbageCollection() const = 0;
/// To query whether algorithm is a child. Default to false /// To query whether algorithm is a child. Default to false
virtual bool isChild() const = 0; virtual bool isChild() const = 0;
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include "MantidKernel/CompositeValidator.h" #include "MantidKernel/CompositeValidator.h"
#include "MantidKernel/ConfigService.h" #include "MantidKernel/ConfigService.h"
#include "MantidKernel/DateAndTime.h"
#include "MantidKernel/EmptyValues.h" #include "MantidKernel/EmptyValues.h"
#include "MantidKernel/MultiThreaded.h" #include "MantidKernel/MultiThreaded.h"
#include "MantidKernel/PropertyWithValue.h" #include "MantidKernel/PropertyWithValue.h"
...@@ -51,6 +50,10 @@ namespace { ...@@ -51,6 +50,10 @@ namespace {
/// Separator for workspace types in workspaceMethodOnTypes member /// Separator for workspace types in workspaceMethodOnTypes member
const std::string WORKSPACE_TYPES_SEPARATOR = ";"; const std::string WORKSPACE_TYPES_SEPARATOR = ";";
/// The minimum number of seconds after execution that the algorithm should be kept alive
/// before garbage collection
const size_t DELAY_BEFORE_GC = 5;
class WorkspacePropertyValueIs { class WorkspacePropertyValueIs {
public: public:
explicit WorkspacePropertyValueIs(const std::string &value) explicit WorkspacePropertyValueIs(const std::string &value)
...@@ -108,7 +111,7 @@ Algorithm::Algorithm() ...@@ -108,7 +111,7 @@ Algorithm::Algorithm()
m_communicator(std::make_unique<Parallel::Communicator>()) {} m_communicator(std::make_unique<Parallel::Communicator>()) {}
/// Virtual destructor /// Virtual destructor
Algorithm::~Algorithm() {} Algorithm::~Algorithm() {}
//============================================================================================= //=============================================================================================
//================================== Simple Getters/Setters //================================== Simple Getters/Setters
...@@ -196,6 +199,15 @@ bool Algorithm::isRunning() const { ...@@ -196,6 +199,15 @@ bool Algorithm::isRunning() const {
return (executionState() == ExecutionState::Running); return (executionState() == ExecutionState::Running);
} }
/// True if the algorithm is ready for garbage collection.
bool Algorithm::isReadyForGarbageCollection() const {
if ((executionState() == ExecutionState::Finished) &&
(Mantid::Types::Core::DateAndTime::getCurrentTime() > m_gcTime)) {
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------
/** Add an observer to a notification /** Add an observer to a notification
@param observer :: Reference to the observer to add @param observer :: Reference to the observer to add
...@@ -671,10 +683,12 @@ bool Algorithm::executeInternal() { ...@@ -671,10 +683,12 @@ bool Algorithm::executeInternal() {
" seconds\n"); " seconds\n");
reportCompleted(duration); reportCompleted(duration);
} catch (std::runtime_error &ex) { } catch (std::runtime_error &ex) {
m_gcTime = Mantid::Types::Core::DateAndTime::getCurrentTime() +=
(Mantid::Types::Core::DateAndTime::ONE_SECOND * DELAY_BEFORE_GC);
setResultState(ResultState::Failed);
notificationCenter().postNotification( notificationCenter().postNotification(
new ErrorNotification(this, ex.what())); new ErrorNotification(this, ex.what()));
this->unlockWorkspaces(); this->unlockWorkspaces();
setResultState(ResultState::Failed);
if (m_isChildAlgorithm || m_runningAsync || m_rethrow) if (m_isChildAlgorithm || m_runningAsync || m_rethrow)
throw; throw;
else { else {
...@@ -686,8 +700,10 @@ bool Algorithm::executeInternal() { ...@@ -686,8 +700,10 @@ bool Algorithm::executeInternal() {
} catch (std::logic_error &ex) { } catch (std::logic_error &ex) {
notificationCenter().postNotification( notificationCenter().postNotification(
new ErrorNotification(this, ex.what())); new ErrorNotification(this, ex.what()));
this->unlockWorkspaces();
setResultState(ResultState::Failed); setResultState(ResultState::Failed);
this->unlockWorkspaces();
m_gcTime = Mantid::Types::Core::DateAndTime::getCurrentTime() +=
(Mantid::Types::Core::DateAndTime::ONE_SECOND * DELAY_BEFORE_GC);
if (m_isChildAlgorithm || m_runningAsync || m_rethrow) if (m_isChildAlgorithm || m_runningAsync || m_rethrow)
throw; throw;
else { else {
...@@ -698,15 +714,20 @@ bool Algorithm::executeInternal() { ...@@ -698,15 +714,20 @@ bool Algorithm::executeInternal() {
} }
} catch (CancelException &ex) { } catch (CancelException &ex) {
m_runningAsync = false; m_runningAsync = false;
m_gcTime = Mantid::Types::Core::DateAndTime::getCurrentTime() +=
(Mantid::Types::Core::DateAndTime::ONE_SECOND * DELAY_BEFORE_GC);
setResultState(ResultState::Failed);
getLogger().warning() << this->name() << ": Execution cancelled by user.\n"; getLogger().warning() << this->name() << ": Execution cancelled by user.\n";
notificationCenter().postNotification( notificationCenter().postNotification(
new ErrorNotification(this, ex.what())); new ErrorNotification(this, ex.what()));
this->unlockWorkspaces(); this->unlockWorkspaces();
setResultState(ResultState::Failed);
throw; throw;
} }
// Gaudi also specifically catches GaudiException & std:exception. // Gaudi also specifically catches GaudiException & std:exception.
catch (std::exception &ex) { catch (std::exception &ex) {
m_gcTime = Mantid::Types::Core::DateAndTime::getCurrentTime() +=
(Mantid::Types::Core::DateAndTime::ONE_SECOND * DELAY_BEFORE_GC);
setResultState(ResultState::Failed); setResultState(ResultState::Failed);
m_runningAsync = false; m_runningAsync = false;
...@@ -723,22 +744,26 @@ bool Algorithm::executeInternal() { ...@@ -723,22 +744,26 @@ bool Algorithm::executeInternal() {
// Execution failed with an unknown exception object // Execution failed with an unknown exception object
m_runningAsync = false; m_runningAsync = false;
m_gcTime = Mantid::Types::Core::DateAndTime::getCurrentTime() +=
(Mantid::Types::Core::DateAndTime::ONE_SECOND * DELAY_BEFORE_GC);
setResultState(ResultState::Failed);
notificationCenter().postNotification( notificationCenter().postNotification(
new ErrorNotification(this, "UNKNOWN Exception is caught in exec()")); new ErrorNotification(this, "UNKNOWN Exception is caught in exec()"));
getLogger().error() << this->name() getLogger().error() << this->name()
<< ": UNKNOWN Exception is caught in exec()\n"; << ": UNKNOWN Exception is caught in exec()\n";
this->unlockWorkspaces(); this->unlockWorkspaces();
setResultState(ResultState::Failed);
throw; throw;
} }
// Unlock the locked workspaces // Unlock the locked workspaces
this->unlockWorkspaces(); this->unlockWorkspaces();
// Only gets to here if algorithm ended normally m_gcTime = Mantid::Types::Core::DateAndTime::getCurrentTime() +=
notificationCenter().postNotification( (Mantid::Types::Core::DateAndTime::ONE_SECOND * DELAY_BEFORE_GC);
new FinishedNotification(this, true));
setResultState(ResultState::Success); setResultState(ResultState::Success);
// Only gets to here if algorithm ended normally
notificationCenter().postNotification(new FinishedNotification(this, true));
return true; return true;
} }
......
...@@ -193,7 +193,7 @@ size_t AlgorithmManagerImpl::removeFinishedAlgorithms() { ...@@ -193,7 +193,7 @@ size_t AlgorithmManagerImpl::removeFinishedAlgorithms() {
std::copy_if( std::copy_if(
m_managed_algs.cbegin(), m_managed_algs.cend(), m_managed_algs.cbegin(), m_managed_algs.cend(),
std::back_inserter(theCompletedInstances), [](const auto &algorithm) { std::back_inserter(theCompletedInstances), [](const auto &algorithm) {
return (algorithm->executionState() == ExecutionState::Finished); return (algorithm->isReadyForGarbageCollection());
}); });
for (auto completedAlg : theCompletedInstances) { for (auto completedAlg : theCompletedInstances) {
auto itend = m_managed_algs.end(); auto itend = m_managed_algs.end();
......
...@@ -1083,6 +1083,7 @@ add_subdirectory(test) ...@@ -1083,6 +1083,7 @@ add_subdirectory(test)
# Auto-generate exports header # Auto-generate exports header
target_include_directories(Algorithms PUBLIC ${CMAKE_BINARY_DIR}/Framework/Algorithms) target_include_directories(Algorithms PUBLIC ${CMAKE_BINARY_DIR}/Framework/Algorithms)
target_include_directories(Algorithms PUBLIC ${CMAKE_BINARY_DIR}/Framework/Types)
generate_mantid_export_header(Algorithms FALSE) generate_mantid_export_header(Algorithms FALSE)
# Installation settings # Installation settings
......
...@@ -24,6 +24,8 @@ if(CXXTEST_FOUND) ...@@ -24,6 +24,8 @@ if(CXXTEST_FOUND)
set_target_properties(${_pythoninterface_test_target_name} set_target_properties(${_pythoninterface_test_target_name}
PROPERTIES COMPILE_FLAGS "/w44244") PROPERTIES COMPILE_FLAGS "/w44244")
endif() endif()
target_include_directories(${_pythoninterface_test_target_name} PUBLIC ${CMAKE_BINARY_DIR}/Framework/Types)
target_link_libraries(${_pythoninterface_test_target_name} target_link_libraries(${_pythoninterface_test_target_name}
LINK_PRIVATE LINK_PRIVATE
${TCMALLOC_LIBRARIES_LINKTIME} ${TCMALLOC_LIBRARIES_LINKTIME}
......
...@@ -4,6 +4,7 @@ if(CXXTEST_FOUND) ...@@ -4,6 +4,7 @@ if(CXXTEST_FOUND)
) )
cxxtest_add_test(RemoteAlgorithmsTest ${TEST_FILES}) cxxtest_add_test(RemoteAlgorithmsTest ${TEST_FILES})
target_include_directories(RemoteAlgorithmsTest PUBLIC ${CMAKE_BINARY_DIR}/Framework/Types)
target_link_libraries(RemoteAlgorithmsTest target_link_libraries(RemoteAlgorithmsTest
LINK_PRIVATE LINK_PRIVATE
${TCMALLOC_LIBRARIES_LINKTIME} ${TCMALLOC_LIBRARIES_LINKTIME}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment