From da71d31e0014d8e2ae2c4698ea5593457d931ded Mon Sep 17 00:00:00 2001 From: Dan Nixon Date: Mon, 18 Aug 2014 16:40:20 +0100 Subject: [PATCH] Work in progress - run all algorithms on an ActiveMethod Refs #10092 --- Code/Mantid/MantidQt/API/CMakeLists.txt | 3 - .../AbstractAsyncAlgorithmRunner.h | 74 ------ .../API/inc/MantidQtAPI/AlgorithmRunner.h | 27 ++- .../inc/MantidQtAPI/BatchAlgorithmRunner.h | 50 +++- .../API/src/AbstractAsyncAlgorithmRunner.cpp | 136 ----------- .../MantidQt/API/src/AlgorithmRunner.cpp | 68 +++++- .../MantidQt/API/src/BatchAlgorithmRunner.cpp | 227 ++++++++---------- .../API/test/BatchAlgorithmRunnerTest.h | 5 +- .../src/IndirectDataReductionTab.cpp | 2 +- .../CustomInterfaces/src/IndirectMoments.cpp | 3 +- 10 files changed, 222 insertions(+), 373 deletions(-) delete mode 100644 Code/Mantid/MantidQt/API/inc/MantidQtAPI/AbstractAsyncAlgorithmRunner.h delete mode 100644 Code/Mantid/MantidQt/API/src/AbstractAsyncAlgorithmRunner.cpp diff --git a/Code/Mantid/MantidQt/API/CMakeLists.txt b/Code/Mantid/MantidQt/API/CMakeLists.txt index f1bb3912cd76..1e5024413323 100644 --- a/Code/Mantid/MantidQt/API/CMakeLists.txt +++ b/Code/Mantid/MantidQt/API/CMakeLists.txt @@ -1,5 +1,4 @@ set ( SRC_FILES - src/AbstractAsyncAlgorithmRunner.cpp src/AlgorithmDialog.cpp src/AlgorithmInputHistory.cpp src/AlgorithmPropertiesWidget.cpp @@ -39,7 +38,6 @@ set ( SRC_FILES ) set ( MOC_FILES - inc/MantidQtAPI/AbstractAsyncAlgorithmRunner.h inc/MantidQtAPI/AlgorithmDialog.h inc/MantidQtAPI/AlgorithmRunner.h inc/MantidQtAPI/AlgorithmPropertiesWidget.h @@ -69,7 +67,6 @@ set ( MOC_FILES # Include files aren't required, but this makes them appear in Visual Studio set ( INC_FILES ${MOC_FILES} - inc/MantidQtAPI/AbstractAsyncAlgorithmRunner.h inc/MantidQtAPI/AlgorithmInputHistory.h inc/MantidQtAPI/AlgorithmRunner.h inc/MantidQtAPI/BatchAlgorithmRunner.h diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/AbstractAsyncAlgorithmRunner.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/AbstractAsyncAlgorithmRunner.h deleted file mode 100644 index 85d0bbfd5b18..000000000000 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/AbstractAsyncAlgorithmRunner.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef MANTID_API_ABSTRACTASYNCALGORITHMRUNNER_H_ -#define MANTID_API_ABSTRACTASYNCALGORITHMRUNNER_H_ - -#include "DllOption.h" -#include "MantidAPI/Algorithm.h" - -#include -#include - -namespace MantidQt -{ -namespace API -{ - - /**TODO - - Copyright © 2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory - - This file is part of Mantid. - - Mantid is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - Mantid is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - - File change history is stored at: - Code Documentation is available at: - */ - class EXPORT_OPT_MANTIDQT_API AbstractAsyncAlgorithmRunner : public QObject - { - Q_OBJECT - - public: - explicit AbstractAsyncAlgorithmRunner(QObject * parent = 0); - virtual ~AbstractAsyncAlgorithmRunner(); - - Mantid::API::IAlgorithm_sptr getCurrentAlgorithm() const; - - protected: - void startAlgorithm(Mantid::API::IAlgorithm_sptr alg); - void cancelRunningAlgorithm(); - - /// Algorithm notification handlers - void handleAlgorithmFinishedNotification(const Poco::AutoPtr& pNf); - Poco::NObserver m_finishedObserver; - virtual void handleAlgorithmFinish() = 0; - - void handleAlgorithmProgressNotification(const Poco::AutoPtr& pNf); - Poco::NObserver m_progressObserver; - virtual void handleAlgorithmProgress(double p, std::string msg) = 0; - - void handleAlgorithmErrorNotification(const Poco::AutoPtr& pNf); - Poco::NObserver m_errorObserver; - virtual void handleAlgorithmError() = 0; - - /// For the asynchronous call in dynamic rebinning. Holds the result of asyncExecute() algorithm call - Poco::ActiveResult * m_asyncResult; - - /// Reference to the algorithm executing asynchronously. - Mantid::API::IAlgorithm_sptr m_asyncAlg; - }; - -} // namespace API -} // namespace Mantid - -#endif /* MANTID_API_ABSTRACTASYNCALGORITHMRUNNER_H_ */ diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/AlgorithmRunner.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/AlgorithmRunner.h index 664b3f183e69..204ca8cdc458 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/AlgorithmRunner.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/AlgorithmRunner.h @@ -1,8 +1,6 @@ #ifndef MANTID_API_ALGORITHMRUNNER_H_ #define MANTID_API_ALGORITHMRUNNER_H_ -#include "MantidQtAPI/AbstractAsyncAlgorithmRunner.h" - #include "DllOption.h" #include "MantidAPI/Algorithm.h" @@ -13,7 +11,6 @@ namespace MantidQt { namespace API { - /** The AlgorithmRunner is a QObject that encapsulates * methods for running an algorithm asynchronously (in the background) * and feeds-back to a GUI widget. @@ -49,7 +46,7 @@ namespace API File change history is stored at: Code Documentation is available at: */ - class EXPORT_OPT_MANTIDQT_API AlgorithmRunner : public AbstractAsyncAlgorithmRunner + class EXPORT_OPT_MANTIDQT_API AlgorithmRunner : public QObject { Q_OBJECT @@ -67,15 +64,29 @@ namespace API void algorithmComplete(bool error); /// Signal emitted when the algorithm reports progress - void algorithmProgress(double p,const std::string& msg); + void algorithmProgress(double p, const std::string& msg); protected: - void handleAlgorithmFinish(); - void handleAlgorithmProgress(double p, const std::string msg); - void handleAlgorithmError(); + + /// Algorithm notification handlers + void handleAlgorithmFinishedNotification(const Poco::AutoPtr& pNf); + Poco::NObserver m_finishedObserver; + + void handleAlgorithmProgressNotification(const Poco::AutoPtr& pNf); + Poco::NObserver m_progressObserver; + + void handleAlgorithmErrorNotification(const Poco::AutoPtr& pNf); + Poco::NObserver m_errorObserver; + + /// For the asynchronous call in dynamic rebinning. Holds the result of asyncExecute() algorithm call + Poco::ActiveResult * m_asyncResult; + + /// Reference to the algorithm executing asynchronously. + Mantid::API::IAlgorithm_sptr m_asyncAlg; }; + } // namespace API } // namespace Mantid diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/BatchAlgorithmRunner.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/BatchAlgorithmRunner.h index 74b388855405..7f55a7eb49e5 100644 --- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/BatchAlgorithmRunner.h +++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/BatchAlgorithmRunner.h @@ -1,13 +1,16 @@ #ifndef MANTID_API_BATCHALGORITHMRUNNER_H_ #define MANTID_API_BATCHALGORITHMRUNNER_H_ -#include "MantidQtAPI/AbstractAsyncAlgorithmRunner.h" - #include "DllOption.h" #include "MantidAPI/Algorithm.h" #include +#include +#include +#include +#include + namespace MantidQt { namespace API @@ -38,7 +41,21 @@ namespace API Code Documentation is available at: */ - class EXPORT_OPT_MANTIDQT_API BatchAlgorithmRunner : public AbstractAsyncAlgorithmRunner + class BatchNotification : public Poco::Notification + { + public: + BatchNotification(bool inProgress, bool error) : Poco::Notification(), + m_inProgress(inProgress), m_error(error) {} + + bool isInProgress() const { return m_inProgress; } + bool hasError() const { return m_error; } + + private: + bool m_inProgress; + bool m_error; + }; + + class EXPORT_OPT_MANTIDQT_API BatchAlgorithmRunner : public QObject { Q_OBJECT @@ -49,28 +66,37 @@ namespace API explicit BatchAlgorithmRunner(QObject * parent = 0); virtual ~BatchAlgorithmRunner(); - void cancelAll(); void addAlgorithm(Mantid::API::IAlgorithm_sptr algo, AlgorithmRuntimeProps props = AlgorithmRuntimeProps()); - void startBatch(bool stopOnFailure = true); - bool isExecuting(); + bool executeBatch(); + void executeBatchAsync(); + + void stopOnFailure(bool stopOnFailure); signals: void batchComplete(bool error); - void batchProgress(double p, const std::string& currentAlg, const std::string& algMsg); private: - void startNextAlgo(); + Mantid::API::IAlgorithm_sptr getCurrentAlgorithm(); + Poco::NotificationCenter & notificationCenter() const; + + Poco::ActiveResult executeAsync(); + bool executeBatchAsyncImpl(const Poco::Void&); + + bool startAlgo(ConfiguredAlgorithm algorithm); std::deque m_algorithms; size_t m_batchSize; + Mantid::API::IAlgorithm_sptr m_currentAlgorithm; + bool m_stopOnFailure; - bool m_isExecuting; - void handleAlgorithmFinish(); - void handleAlgorithmProgress(double p, const std::string msg); - void handleAlgorithmError(); + Poco::ActiveMethod> m_executeAsync; + mutable Poco::NotificationCenter *m_notificationCenter; + + void handleNotification(const Poco::AutoPtr& pNf); + Poco::NObserver m_notificationObserver; }; } // namespace API diff --git a/Code/Mantid/MantidQt/API/src/AbstractAsyncAlgorithmRunner.cpp b/Code/Mantid/MantidQt/API/src/AbstractAsyncAlgorithmRunner.cpp deleted file mode 100644 index 0019b634fe92..000000000000 --- a/Code/Mantid/MantidQt/API/src/AbstractAsyncAlgorithmRunner.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include "MantidQtAPI/AbstractAsyncAlgorithmRunner.h" - -#include - -using namespace Mantid::Kernel; -using namespace Mantid::API; - -namespace MantidQt -{ -namespace API -{ - - - //---------------------------------------------------------------------------------------------- - /** Constructor - */ - AbstractAsyncAlgorithmRunner::AbstractAsyncAlgorithmRunner(QObject * parent) : QObject(parent), - m_finishedObserver(*this, &AbstractAsyncAlgorithmRunner::handleAlgorithmFinishedNotification), - m_progressObserver(*this, &AbstractAsyncAlgorithmRunner::handleAlgorithmProgressNotification), - m_errorObserver(*this, &AbstractAsyncAlgorithmRunner::handleAlgorithmErrorNotification), - m_asyncResult(NULL) - { - } - - //---------------------------------------------------------------------------------------------- - /** Destructor - */ - AbstractAsyncAlgorithmRunner::~AbstractAsyncAlgorithmRunner() - { - if (m_asyncAlg) - { - m_asyncAlg->removeObserver(m_finishedObserver); - m_asyncAlg->removeObserver(m_errorObserver); - m_asyncAlg->removeObserver(m_progressObserver); - } - delete m_asyncResult; - } - - - //-------------------------------------------------------------------------------------- - /** If an algorithm is already running, cancel it. - * Does nothing if no algorithm is running. This blocks - * for up to 1 second to wait for the algorithm to finish cancelling. - */ - void AbstractAsyncAlgorithmRunner::cancelRunningAlgorithm() - { - // Cancel any currently running algorithms - if (m_asyncAlg) - { - if (m_asyncAlg->isRunning()) - { - m_asyncAlg->cancel(); - } - if (m_asyncResult) - { - m_asyncResult->tryWait(1000); - delete m_asyncResult; - m_asyncResult = NULL; - } - m_asyncAlg->removeObserver(m_finishedObserver); - m_asyncAlg->removeObserver(m_errorObserver); - m_asyncAlg->removeObserver(m_progressObserver); - m_asyncAlg.reset(); - } - } - - //-------------------------------------------------------------------------------------- - /** Begin asynchronous execution of an algorithm and observe its execution - * - * @param alg :: algorithm to execute. All properties should have been set properly. - */ - void AbstractAsyncAlgorithmRunner::startAlgorithm(Mantid::API::IAlgorithm_sptr alg) - { - if (!alg) - throw std::invalid_argument("AbstractAsyncAlgorithmRunner::startAlgorithm() given a NULL Algorithm"); - if (!alg->isInitialized()) - throw std::invalid_argument("AbstractAsyncAlgorithmRunner::startAlgorithm() given an uninitialized Algorithm"); - - cancelRunningAlgorithm(); - - // Start asynchronous execution - m_asyncAlg = alg; - m_asyncResult = new Poco::ActiveResult(m_asyncAlg->executeAsync()); - - // Observe the algorithm - alg->addObserver(m_finishedObserver); - alg->addObserver(m_errorObserver); - alg->addObserver(m_progressObserver); - } - - /// Get back a pointer to the running algorithm - Mantid::API::IAlgorithm_sptr AbstractAsyncAlgorithmRunner::getCurrentAlgorithm() const - { - return m_asyncAlg; - } - - //-------------------------------------------------------------------------------------- - /** Observer called when the asynchronous algorithm has completed. - * - * Calls handler defined in concrete class - * - * @param pNf :: finished notification object. - */ - void AbstractAsyncAlgorithmRunner::handleAlgorithmFinishedNotification(const Poco::AutoPtr& pNf) - { - UNUSED_ARG(pNf); - handleAlgorithmFinish(); - } - - //-------------------------------------------------------------------------------------- - /** Observer called when the async algorithm has progress to report - * - * Calls handler defined in concrete class - * - * @param pNf :: notification object - */ - void AbstractAsyncAlgorithmRunner::handleAlgorithmProgressNotification(const Poco::AutoPtr& pNf) - { - handleAlgorithmProgress(pNf->progress, pNf->message); - } - - //-------------------------------------------------------------------------------------- - /** Observer called when the async algorithm has encountered an error. - * - * Calls handler defined in concrete class - * - * @param pNf :: notification object - */ - void AbstractAsyncAlgorithmRunner::handleAlgorithmErrorNotification(const Poco::AutoPtr& pNf) - { - UNUSED_ARG(pNf); - handleAlgorithmError(); - } - -} // namespace Mantid -} // namespace API diff --git a/Code/Mantid/MantidQt/API/src/AlgorithmRunner.cpp b/Code/Mantid/MantidQt/API/src/AlgorithmRunner.cpp index f2f8a1ce0edf..b02e5c453155 100644 --- a/Code/Mantid/MantidQt/API/src/AlgorithmRunner.cpp +++ b/Code/Mantid/MantidQt/API/src/AlgorithmRunner.cpp @@ -10,10 +10,15 @@ namespace MantidQt namespace API { + //---------------------------------------------------------------------------------------------- /** Constructor */ - AlgorithmRunner::AlgorithmRunner(QObject * parent) : AbstractAsyncAlgorithmRunner(parent) + AlgorithmRunner::AlgorithmRunner(QObject * parent) : QObject(parent), + m_finishedObserver(*this, &AlgorithmRunner::handleAlgorithmFinishedNotification), + m_progressObserver(*this, &AlgorithmRunner::handleAlgorithmProgressNotification), + m_errorObserver(*this, &AlgorithmRunner::handleAlgorithmErrorNotification), + m_asyncResult(NULL) { } @@ -22,6 +27,13 @@ namespace API */ AlgorithmRunner::~AlgorithmRunner() { + if (m_asyncAlg) + { + m_asyncAlg->removeObserver(m_finishedObserver); + m_asyncAlg->removeObserver(m_errorObserver); + m_asyncAlg->removeObserver(m_progressObserver); + } + delete m_asyncResult; } @@ -32,7 +44,24 @@ namespace API */ void AlgorithmRunner::cancelRunningAlgorithm() { - AbstractAsyncAlgorithmRunner::cancelRunningAlgorithm(); + // Cancel any currently running algorithms + if (m_asyncAlg) + { + if (m_asyncAlg->isRunning()) + { + m_asyncAlg->cancel(); + } + if (m_asyncResult) + { + m_asyncResult->tryWait(1000); + delete m_asyncResult; + m_asyncResult = NULL; + } + m_asyncAlg->removeObserver(m_finishedObserver); + m_asyncAlg->removeObserver(m_errorObserver); + m_asyncAlg->removeObserver(m_progressObserver); + m_asyncAlg.reset(); + } } //-------------------------------------------------------------------------------------- @@ -42,13 +71,27 @@ namespace API */ void AlgorithmRunner::startAlgorithm(Mantid::API::IAlgorithm_sptr alg) { - AbstractAsyncAlgorithmRunner::startAlgorithm(alg); + if (!alg) + throw std::invalid_argument("AlgorithmRunner::startAlgorithm() given a NULL Algorithm"); + if (!alg->isInitialized()) + throw std::invalid_argument("AlgorithmRunner::startAlgorithm() given an uninitialized Algorithm"); + + cancelRunningAlgorithm(); + + // Start asynchronous execution + m_asyncAlg = alg; + m_asyncResult = new Poco::ActiveResult(m_asyncAlg->executeAsync()); + + // Observe the algorithm + alg->addObserver(m_finishedObserver); + alg->addObserver(m_errorObserver); + alg->addObserver(m_progressObserver); } /// Get back a pointer to the running algorithm Mantid::API::IAlgorithm_sptr AlgorithmRunner::getAlgorithm() const { - return getCurrentAlgorithm(); + return m_asyncAlg; } //-------------------------------------------------------------------------------------- @@ -58,29 +101,34 @@ namespace API * * This is called in a separate (non-GUI) thread and so * CANNOT directly change the gui. + * + * @param pNf :: finished notification object. */ - void AlgorithmRunner::handleAlgorithmFinish() + void AlgorithmRunner::handleAlgorithmFinishedNotification(const Poco::AutoPtr& pNf) { + UNUSED_ARG(pNf); emit algorithmComplete(false); } //-------------------------------------------------------------------------------------- /** Observer called when the async algorithm has progress to report * - * @param p Completion percentage - * @param msg Progress message + * @param pNf :: notification object */ - void AlgorithmRunner::handleAlgorithmProgress(double p, const std::string msg) + void AlgorithmRunner::handleAlgorithmProgressNotification(const Poco::AutoPtr& pNf) { - emit algorithmProgress(p, msg); + emit algorithmProgress(pNf->progress, pNf->message); } //-------------------------------------------------------------------------------------- /** Observer called when the async algorithm has encountered an error. * Emits a signal for the GUI widget + * + * @param pNf :: notification object */ - void AlgorithmRunner::handleAlgorithmError() + void AlgorithmRunner::handleAlgorithmErrorNotification(const Poco::AutoPtr& pNf) { + UNUSED_ARG(pNf); emit algorithmComplete(true); } diff --git a/Code/Mantid/MantidQt/API/src/BatchAlgorithmRunner.cpp b/Code/Mantid/MantidQt/API/src/BatchAlgorithmRunner.cpp index e4d9eda36d8f..25de27b705e4 100644 --- a/Code/Mantid/MantidQt/API/src/BatchAlgorithmRunner.cpp +++ b/Code/Mantid/MantidQt/API/src/BatchAlgorithmRunner.cpp @@ -14,24 +14,30 @@ namespace MantidQt { namespace API { - BatchAlgorithmRunner::BatchAlgorithmRunner(QObject * parent) : AbstractAsyncAlgorithmRunner(parent), - m_stopOnFailure(true), m_isExecuting(false) + BatchAlgorithmRunner::BatchAlgorithmRunner(QObject * parent) : QObject(parent), + m_stopOnFailure(true), + m_executeAsync(this, &BatchAlgorithmRunner::executeBatchAsyncImpl), + m_notificationObserver(*this, &BatchAlgorithmRunner::handleNotification) { } BatchAlgorithmRunner::~BatchAlgorithmRunner() { - cancelAll(); } - + /** - * Checks to see if any algorithms are currently being executed + * Gets a pointer to the current algorithm being executed * - * @return True if algorithms are being executed, false otherwise + * @return Current algorithm */ - bool BatchAlgorithmRunner::isExecuting() + IAlgorithm_sptr BatchAlgorithmRunner::getCurrentAlgorithm() { - return m_isExecuting; + return m_currentAlgorithm; + } + + void BatchAlgorithmRunner::stopOnFailure(bool stopOnFailure) + { + m_stopOnFailure = stopOnFailure; } /** @@ -42,157 +48,130 @@ namespace API */ void BatchAlgorithmRunner::addAlgorithm(IAlgorithm_sptr algo, AlgorithmRuntimeProps props) { - if(m_isExecuting) - { - g_log.warning("Cannot add algorithm to queue whilst it is executing"); - return; - } - m_algorithms.push_back(std::make_pair(algo, props)); g_log.debug() << "Added algorithm \"" << m_algorithms.back().first->name() << "\" to batch queue\n"; } /** - * Cancels all algorithms and discards the queue + * Starts executing the queue of algorithms + * + * @return False if the batch was stopped due to error */ - void BatchAlgorithmRunner::cancelAll() + bool BatchAlgorithmRunner::executeBatch() { - m_isExecuting = false; - - // Clear queue - m_algorithms.clear(); + bool cancelFlag = false; - // If an algorithm is running, stop it - if(isExecuting()) + for(auto it = m_algorithms.begin(); it != m_algorithms.end(); ++it) { - cancelRunningAlgorithm(); + if(!startAlgo(*it)) + { + g_log.warning() << "Got error from algorithm \"" << getCurrentAlgorithm()->name() << "\"\n"; + if(m_stopOnFailure) + { + g_log.warning("Stopping batch algorithm because of execution error"); + notificationCenter().postNotification(new BatchNotification(false, true)); + cancelFlag = true; + break; + } + } + else + { + g_log.information() << "Algorithm \"" << getCurrentAlgorithm()->name() << "\" finished\n"; + } } - } - /** - * Starts executing the queue of algorithms - * - * @param stopOnFailure Stop executing queue if an algorithm fails - */ - void BatchAlgorithmRunner::startBatch(bool stopOnFailure) - { - // Do nothing if a batch is already running - if(m_isExecuting) + if(cancelFlag) { - return; - } + // Clear queue + m_algorithms.clear(); - m_stopOnFailure = stopOnFailure; - m_batchSize = m_algorithms.size(); + return false; + } - startNextAlgo(); + m_currentAlgorithm = NULL; + try + { + notificationCenter().postNotification(new BatchNotification(false, false)); + } + catch(Poco::SystemException &pse) + { + g_log.warning() << pse.message() << "\n"; + } + return true; } - - /** - * Handle notification when an algorithm in the queue has completed without error - */ - void BatchAlgorithmRunner::handleAlgorithmFinish() + + void BatchAlgorithmRunner::executeBatchAsync() { - startNextAlgo(); + notificationCenter().addObserver(m_notificationObserver); + Poco::ActiveResult result = m_executeAsync(Poco::Void()); } - /** - * Handle notification when an algorithm reports it's progress - * - * This is used only to provide a Qt signal indicating the progress of the entire queue - */ - void BatchAlgorithmRunner::handleAlgorithmProgress(const double p, const std::string msg) + bool BatchAlgorithmRunner::executeBatchAsyncImpl(const Poco::Void&) { - double percentPerAlgo = (1.0 / (double)m_batchSize); - double batchPercentDone = (percentPerAlgo * static_cast(m_batchSize - m_algorithms.size() - 1)) - + (percentPerAlgo * p); - - std::string currentAlgo = getCurrentAlgorithm()->name(); - - emit batchProgress(batchPercentDone, currentAlgo, msg); + return executeBatch(); } /** - * Handle notification when an algorithm in the queue has failed + * Assigns properties to an algorithm then starts it * - * This can either continue to the next algorithm regardless or stop the entire queue - */ - void BatchAlgorithmRunner::handleAlgorithmError() - { - g_log.warning() << "Got error from algorithm \"" << getCurrentAlgorithm()->name() << "\"\n"; - - if(m_stopOnFailure) - { - g_log.warning("Stopping batch algorithm because of execution error"); - cancelAll(); - return; - } - - startNextAlgo(); - } - - /** - * Starts the next anglorithm in the queue + * @param algorithm Algorithm and properties to assign to it + * @return False if algorithm execution failed */ - void BatchAlgorithmRunner::startNextAlgo() + bool BatchAlgorithmRunner::startAlgo(ConfiguredAlgorithm algorithm) { - if(!m_algorithms.empty()) + try { - ConfiguredAlgorithm nextAlgo = m_algorithms.front(); - m_algorithms.pop_front(); + m_currentAlgorithm = algorithm.first; - try + // Assign the properties to be set at runtime + for(auto it = algorithm.second.begin(); it != algorithm.second.end(); ++it) { - // Assign the properties to be set at runtime - for(auto it = nextAlgo.second.begin(); it != nextAlgo.second.end(); ++it) - { - nextAlgo.first->setProperty(it->first, it->second); - } - - // Start algorithm running - g_log.information() << "Starting next algorithm in queue: " << nextAlgo.first->name() << "\n"; - startAlgorithm(nextAlgo.first); - - // Set execution flag - m_isExecuting = true; + m_currentAlgorithm->setProperty(it->first, it->second); } - // If a property name was given that does not match a property - catch(Mantid::Kernel::Exception::NotFoundError ¬FoundEx) - { - UNUSED_ARG(notFoundEx); - g_log.warning("Algorithm property does not exist.\nStopping queue execution."); + g_log.information() << "Starting next algorithm in queue: " << m_currentAlgorithm->name() << "\n"; - cancelAll(); - emit batchComplete(true); - } - // If a property was assigned a value of the wrong type - catch(std::invalid_argument &invalidArgEx) - { - UNUSED_ARG(invalidArgEx); - - g_log.warning("Algorithm property given value of incorrect type.\nStopping queue execution."); - - cancelAll(); - emit batchComplete(true); - } - catch(std::exception &exc) - { - UNUSED_ARG(exc); + // Start algorithm running + return m_currentAlgorithm->execute(); + } + // If a property name was given that does not match a property + catch(Mantid::Kernel::Exception::NotFoundError ¬FoundEx) + { + UNUSED_ARG(notFoundEx); + g_log.warning("Algorithm property does not exist.\nStopping queue execution."); + notificationCenter().postNotification(new BatchNotification(false, true)); + return false; + } + // If a property was assigned a value of the wrong type + catch(std::invalid_argument &invalidArgEx) + { + UNUSED_ARG(invalidArgEx); + g_log.warning("Algorithm property given value of incorrect type.\nStopping queue execution."); + notificationCenter().postNotification(new BatchNotification(false, true)); + return false; + } + catch(std::exception &exc) + { + UNUSED_ARG(exc); + g_log.warning("Unknown error starting next batch algorithm"); + notificationCenter().postNotification(new BatchNotification(false, true)); + return false; + } + } - g_log.warning("Unknown error starting next batch algorithm"); + Poco::NotificationCenter & BatchAlgorithmRunner::notificationCenter() const + { + if(!m_notificationCenter) m_notificationCenter = new Poco::NotificationCenter; + return *m_notificationCenter; + } - cancelAll(); - emit batchComplete(true); - } - } - else + void BatchAlgorithmRunner::handleNotification(const Poco::AutoPtr& pNf) + { + /* m_isExecuting = pNf->isInProgress(); */ + if(!pNf->isInProgress()) { - // Reached end of queue, notify GUI - g_log.information("Batch algorithm queue empty"); - m_isExecuting = false; - emit batchComplete(false); + emit batchComplete(pNf->hasError()); } } diff --git a/Code/Mantid/MantidQt/API/test/BatchAlgorithmRunnerTest.h b/Code/Mantid/MantidQt/API/test/BatchAlgorithmRunnerTest.h index 9f13964dad26..266d42ce2736 100644 --- a/Code/Mantid/MantidQt/API/test/BatchAlgorithmRunnerTest.h +++ b/Code/Mantid/MantidQt/API/test/BatchAlgorithmRunnerTest.h @@ -62,10 +62,7 @@ class BatchAlgorithmRunnerTest : public CxxTest::TestSuite runner.addAlgorithm(scaleWsAlg, scaleRuntimeProps); // Run queue - runner.startBatch(); - - // Wait for queue completion - while(runner.isExecuting()) {} + runner.executeBatch(); // Get workspace history std::string wsName = "BatchAlgorithmRunnerTest_Scale"; diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataReductionTab.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataReductionTab.cpp index d4e7f3434aaa..c55e51b5a00f 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataReductionTab.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectDataReductionTab.cpp @@ -290,7 +290,7 @@ namespace CustomInterfaces { algorithm->setRethrows(true); m_batchAlgoRunner->addAlgorithm(algorithm); - m_batchAlgoRunner->startBatch(); + m_batchAlgoRunner->executeBatchAsync(); } /** diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectMoments.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectMoments.cpp index 036654368cb4..5b3dc7e40af7 100644 --- a/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectMoments.cpp +++ b/Code/Mantid/MantidQt/CustomInterfaces/src/IndirectMoments.cpp @@ -111,7 +111,8 @@ namespace CustomInterfaces } //execute algorithm on seperate thread - m_batchAlgoRunner->startBatch(); + m_batchAlgoRunner->executeBatchAsync(); + /* m_batchAlgoRunner->executeBatch(); */ } bool IndirectMoments::validate()