NRP Core  1.4.1
process_launcher.h
Go to the documentation of this file.
1 /* * NRP Core - Backend infrastructure to synchronize simulations
2  *
3  * Copyright 2020-2023 NRP Team
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * This project has received funding from the European Union’s Horizon 2020
18  * Framework Programme for Research and Innovation under the Specific Grant
19  * Agreement No. 945539 (Human Brain Project SGA3).
20  */
21 
22 #ifndef PROCESS_LAUNCHER_H
23 #define PROCESS_LAUNCHER_H
24 
28 
30 
35  : public PtrTemplates<ProcessLauncherInterface>
36 {
37  public:
38  // Process status options
40  static constexpr auto UNKNOWN = LaunchCommandInterface::ENGINE_RUNNING_STATUS::UNKNOWN;
41  static constexpr auto RUNNING = LaunchCommandInterface::ENGINE_RUNNING_STATUS::RUNNING;
42  static constexpr auto STOPPED = LaunchCommandInterface::ENGINE_RUNNING_STATUS::STOPPED;
43 
44  virtual ~ProcessLauncherInterface() = default;
45 
49  virtual std::string launcherName() const = 0;
50 
55  virtual ProcessLauncherInterface::unique_ptr createLauncher(int logFD = -1) = 0;
56 
63  virtual pid_t launchProcess(nlohmann::json procConfig, bool appendParentEnv = true) = 0;
64 
70  virtual pid_t stopProcess(unsigned int killWait) = 0;
71 
77  { return this->_launchCmd ? this->_launchCmd->getProcessStatus() : ENGINE_RUNNING_STATUS::UNKNOWN; }
78 
83 
88  void setFileDescriptor(int logFD);
89 
90  protected:
96  static bool checkEnvVar(const std::string &envVar);
97 
103  static std::tuple<std::string,std::string> splitEnvVar(const std::string &envVar);
104 
109 
113  int _logFD = -1;
114 };
115 
116 
122 template<class PROCESS_LAUNCHER,const char *LAUNCHER_TYPE, class ...LAUNCHER_COMMANDS>
124  : public ProcessLauncherInterface
125 {
126  public:
127  static constexpr auto LauncherType = LAUNCHER_TYPE;
128 
130  static_assert((std::is_base_of_v<LaunchCommandInterface, LAUNCHER_COMMANDS> && ...) ,"Parameter LAUNCHER_COMMANDS must derive from LaunchCommandInterface");
131  static_assert((std::is_convertible_v<const volatile LAUNCHER_COMMANDS*, const volatile LaunchCommandInterface*> && ...),"Parameter LAUNCHER_COMMANDS must be convertible to LaunchCommandInterface");
132  }
133 
134  ~ProcessLauncher() override = default;
135 
137  {
138  ProcessLauncherInterface::unique_ptr launcher(new PROCESS_LAUNCHER());
139  launcher->setFileDescriptor(logFD);
140  return launcher;
141  }
142 
143  std::string launcherName() const override final
144  { return std::string(LauncherType); }
145 
146  pid_t launchProcess(nlohmann::json procConfig, bool appendParentEnv = true) override final
147  {
148  json_utils::validateJson(procConfig, "json://nrp-core/process_launcher.json#ProcessLauncher");
149 
150  nlohmann::json launcherConfig = procConfig.at("LaunchCommand");
151 
152  if constexpr (sizeof...(LAUNCHER_COMMANDS) == 0)
153  { throw noLauncherFound(launcherConfig.at("LaunchType")); }
154 
155  this->_launchCmd = ProcessLauncher::findLauncher<LAUNCHER_COMMANDS...>(launcherConfig.at("LaunchType"));
156  return this->_launchCmd->launchProcess(launcherConfig, procConfig.at("ProcCmd"),
157  procConfig.contains("ProcEnvParams") ? procConfig.at("ProcEnvParams").get<std::vector<std::string>>() : std::vector<std::string>(),
158  procConfig.contains("ProcStartParams") ? procConfig.at("ProcStartParams").get<std::vector<std::string>>() : std::vector<std::string>(),
159  appendParentEnv,
160  _logFD);
161  }
162 
163  pid_t stopProcess(unsigned int killWait) override final
164  { return this->_launchCmd->stopProcess(killWait); }
165 
166  private:
167  template<class LAUNCH_CMD, class ...REST>
168  inline LaunchCommandInterface::unique_ptr findLauncher(const std::string &launchCmd)
169  {
170  if(std::string(LAUNCH_CMD::LaunchType) == launchCmd)
171  return LaunchCommandInterface::unique_ptr(new LAUNCH_CMD());
172  else
173  {
174  if constexpr (sizeof...(REST) > 0)
175  { return findLauncher<REST...>(launchCmd); }
176  else
177  { throw noLauncherFound(launchCmd); }
178  }
179  }
180 
181  static inline std::runtime_error noLauncherFound(const std::string &launchCmd)
182  { return std::runtime_error("Unable to find launcher with name \"" + launchCmd + "\""); }
183 };
184 
185 #endif // PROCESS_LAUNCHER_H
ProcessLauncherInterface::stopProcess
virtual pid_t stopProcess(unsigned int killWait)=0
Stop a running process.
ProcessLauncherInterface::launcherName
virtual std::string launcherName() const =0
Get name of launcher.
fixed_string.h
ProcessLauncherInterface
Functions for all process launchers.
Definition: process_launcher.h:34
PtrTemplates< ProcessLauncherInterface >::unique_ptr
std::unique_ptr< ProcessLauncherInterface > unique_ptr
Definition: ptr_templates.h:34
json_utils::validateJson
void validateJson(nlohmann::json &instance, std::string schema_path, bool addPatch)
Validates a json object using a given json schema.
Definition: json_schema_utils.cpp:65
ProcessLauncher::ProcessLauncher
ProcessLauncher()
Definition: process_launcher.h:129
ProcessLauncher::launchProcess
pid_t launchProcess(nlohmann::json procConfig, bool appendParentEnv=true) override final
Fork a new process. Will read environment variables and start params from procConfig.
Definition: process_launcher.h:146
ProcessLauncher::launcherName
std::string launcherName() const override final
Get name of launcher.
Definition: process_launcher.h:143
launch_command.h
ProcessLauncher::~ProcessLauncher
~ProcessLauncher() override=default
ProcessLauncherInterface::launchCommand
LaunchCommandInterface * launchCommand() const
Get Launch Command. If launchProcess has not yet been called, return nullptr.
Definition: process_launcher.cpp:26
ProcessLauncherInterface::_launchCmd
LaunchCommandInterface::unique_ptr _launchCmd
Launch Command.
Definition: process_launcher.h:108
ProcessLauncher::stopProcess
pid_t stopProcess(unsigned int killWait) override final
Stop a running process.
Definition: process_launcher.h:163
LaunchCommandInterface
Definition: launch_command.h:32
PtrTemplates
Definition: ptr_templates.h:28
ProcessLauncherInterface::_logFD
int _logFD
File descriptor to route stdout and stderror outputs in launched process.
Definition: process_launcher.h:113
ProcessLauncher
Base class for all process launchers.
Definition: process_launcher.h:123
ptr_templates.h
json_schema_utils.h
ProcessLauncherInterface::checkEnvVar
static bool checkEnvVar(const std::string &envVar)
Checks given Environment variable for correctness (Should contain an '=' character)
Definition: process_launcher.cpp:29
ProcessLauncher::LauncherType
static constexpr auto LauncherType
Definition: process_launcher.h:127
ProcessLauncher::createLauncher
ProcessLauncherInterface::unique_ptr createLauncher(int logFD=-1) override
Create a new process launcher.
Definition: process_launcher.h:136
LaunchCommandInterface::ENGINE_RUNNING_STATUS
ENGINE_RUNNING_STATUS
Engine Process status.
Definition: launch_command.h:39
ProcessLauncherInterface::STOPPED
static constexpr auto STOPPED
Definition: process_launcher.h:42
ProcessLauncherInterface::UNKNOWN
static constexpr auto UNKNOWN
Definition: process_launcher.h:40
ProcessLauncherInterface::RUNNING
static constexpr auto RUNNING
Definition: process_launcher.h:41
ProcessLauncherInterface::createLauncher
virtual ProcessLauncherInterface::unique_ptr createLauncher(int logFD=-1)=0
Create a new process launcher.
ProcessLauncherInterface::splitEnvVar
static std::tuple< std::string, std::string > splitEnvVar(const std::string &envVar)
Split Environment variable string into variable name and value.
Definition: process_launcher.cpp:32
ProcessLauncherInterface::launchProcess
virtual pid_t launchProcess(nlohmann::json procConfig, bool appendParentEnv=true)=0
Fork a new process. Will read environment variables and start params from procConfig.
ProcessLauncherInterface::setFileDescriptor
void setFileDescriptor(int logFD)
Sets the file descriptor that will be used by the launched process to write stdout and stderror.
Definition: process_launcher.cpp:41
ProcessLauncherInterface::getProcessStatus
virtual ENGINE_RUNNING_STATUS getProcessStatus()
Get the current process status. If status cannot be retrieved, return ENGINE_RUNNING_STATUS::UNKNOWN.
Definition: process_launcher.h:76
ProcessLauncherInterface::~ProcessLauncherInterface
virtual ~ProcessLauncherInterface()=default
json
nlohmann::json json
Definition: engine_json_server.cpp:31