ChimeraTK-ApplicationCore 04.08.00
Loading...
Searching...
No Matches
ScriptedInitialisationHandler.cc
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
4
5#include "DeviceModule.h"
6
7#include <boost/process.hpp>
8
9#include <functional>
10#include <utility>
11namespace bp = boost::process;
12
13namespace ChimeraTK {
14
15 /********************************************************************************************************************/
16
17 ScriptedInitHandler::ScriptedInitHandler(ModuleGroup* owner, const std::string& name, const std::string& description,
18 std::string command, DeviceModule& deviceModule, std::string outputName, std::string exitCodeName,
19 unsigned int errorGracePeriod)
20 : ApplicationModule(owner, name, description), _command(std::move(command)),
21 _deviceAlias(deviceModule.getDeviceAliasOrURI()), _outputName(std::move(outputName)),
22 _exitCodeName(std::move(exitCodeName)), _errorGracePeriod(errorGracePeriod) {
23 deviceModule.addInitialisationHandler([this](Device&) { doInit(); });
24 }
25 /********************************************************************************************************************/
26
27 ScriptedInitHandler::ScriptedInitHandler(ModuleGroup* owner, const std::string& name, const std::string& description,
28 std::string command, DeviceModule& deviceModule, std::string outputName, unsigned int errorGracePeriod)
29 : ScriptedInitHandler(owner, name, description, std::move(command), deviceModule, std::move(outputName),
30 "initScriptExitCode", errorGracePeriod) {}
31
32 /********************************************************************************************************************/
33
35 std::string output;
37
38 try {
39 bp::ipstream out;
40 bp::child initScript(_command, (bp::std_out & bp::std_err) > out);
41 std::string line;
42 // Publish every line that is read from the script. It is appended to the output string
43 // such that a growing message is published.
44 // For debugging it is important to get the intermediate information. In case the script gets stuck
45 // you want to know what has already been printed.
46 while(std::getline(out, line)) {
47 output += line + "\n";
49 }
50 initScript.wait();
51
52 _scriptExitCode.setAndWrite(initScript.exit_code());
53
54 if(_scriptExitCode != 0) {
55 output += "!!! " + _deviceAlias + " initialisation FAILED!";
57 if(!_lastFailed) {
58 ChimeraTK::logger(Logger::Severity::error, "Device " + _deviceAlias) << output << std::endl;
59 }
60 _lastFailed = true;
61 std::this_thread::sleep_for(std::chrono::seconds(_errorGracePeriod));
62 throw ChimeraTK::runtime_error(_deviceAlias + " initialisation failed.");
63 }
64 output += _deviceAlias + " initialisation SUCCESS!";
66 ChimeraTK::logger(Logger::Severity::info, "Device " + _deviceAlias) << output << std::endl;
67 _lastFailed = false;
68 }
69 catch(bp::process_error& e) {
70 // this
71 throw ChimeraTK::logic_error("Caught boost::process::process_error while executing \"" + _command +
72 "\" for device " + _deviceAlias + ": " + e.what());
73 }
74 }
75
76 /********************************************************************************************************************/
77} // namespace ChimeraTK
void addInitialisationHandler(std::function< void(ChimeraTK::Device &)> initialisationHandler)
void setAndWrite(UserType newValue, VersionNumber versionNumber)=delete
InvalidityTracer application module.
Logger::StreamProxy logger(Logger::Severity severity, std::string context)
Convenience function to obtain the logger stream.
Definition Logger.h:124
Initialisation handler which calls an external application (usually a script), captures its output (b...
ScriptedInitHandler(ModuleGroup *owner, const std::string &name, const std::string &description, std::string command, DeviceModule &deviceModule, std::string outputName="initScriptOutput", std::string exitCodeName="initScriptExitCode", unsigned int errorGracePeriod=10)
Constructor.