Newer
Older
#include "ScriptedInitialisationHandler.h"
#include "DeviceModule.h"
#include <boost/process.hpp>
#include <functional>
namespace bp = boost::process;
namespace ChimeraTK {
/**********************************************************************************************************************/
ScriptedInitHandler::ScriptedInitHandler(EntityOwner* owner, const std::string& name, const std::string& description,
const std::string& command, DeviceModule& deviceModule, const std::string& outputName,
unsigned int errorGracePeriod)
: ApplicationModule(owner, name, description), _command(command), _deviceAlias(deviceModule.getDeviceAliasOrURI()),
_outputName(outputName), _errorGracePeriod(errorGracePeriod) {
deviceModule.addInitialisationHandler(std::bind(&ScriptedInitHandler::doInit, this));
}
/**********************************************************************************************************************/
void ScriptedInitHandler::doInit() {
std::string output;
_scriptOutput.value = "";
_scriptOutput.value.write();
Martin Killenberg
committed
try {
bp::ipstream out;
bp::child initScript(_command, (bp::std_out & bp::std_err) > out);
std::string line;
// Publish every line that is read from the script. It is appended to the output string
// such that a growing message is published.
// For debugging it is important to get the intermediate information. In case the script gets stuck
// you want to know what has already been printed.
while(initScript.running() && std::getline(out, line)) {
output += line + "\n";
_scriptOutput.value = output;
_scriptOutput.value.write();
}
initScript.wait();
Martin Killenberg
committed
if(initScript.exit_code() != 0) {
output += "!!! " + _deviceAlias + " initialisation FAILED!";
_scriptOutput.value = output;
_scriptOutput.value.write();
if(!_lastFailed) {
std::cerr << output << std::endl;
}
_lastFailed = true;
std::this_thread::sleep_for(std::chrono::seconds(_errorGracePeriod));
throw ChimeraTK::runtime_error(_deviceAlias + " initialisation failed.");
Martin Killenberg
committed
}
else {
output += _deviceAlias + " initialisation SUCCESS!";
_scriptOutput.value = output;
_scriptOutput.value.write();
std::cerr << output << std::endl;
Martin Killenberg
committed
_lastFailed = false;
Martin Killenberg
committed
catch(bp::process_error& e) {
// this
throw ChimeraTK::logic_error("Caught boost::process::process_error while executing \"" + _command +
"\" for device " + _deviceAlias + ": " + e.what());
}
}
/**********************************************************************************************************************/
} // namespace ChimeraTK