ApplicationInstance.h
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package ArmarXCore::core
19 * @author Dennis Weigelt
20 * @date 2016
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25
26#pragma once
27
28#include "Application.h"
29
31{
33 using ApplicationInstancePtr = std::shared_ptr<ApplicationInstance>;
34 using ApplicationInstanceWPtr = std::weak_ptr<ApplicationInstance>;
35 using ApplicationInstanceVectorPtr = std::shared_ptr<std::vector<ApplicationInstancePtr>>;
36} // namespace ScenarioManager::Data_Structure
37
38#include <atomic>
39#include <memory>
40#include <string>
41#include <vector>
42
43#include "Scenario.h"
44
46{
47 /**
48 * What the ScenarioManager is currently trying to do with an application.
49 *
50 * An intent is *requested* rather than executed: requesting one supersedes any earlier intent
51 * that has not been carried out yet, so the last thing the user asked for is what happens
52 * ("last intent wins"). `None` means no operation is requested or running.
53 *
54 * `Restart` is a separate intent rather than "desired state = running" because it has to bounce
55 * an application that is already running. On a stopped application it simply starts it.
56 */
57 enum class Intent
58 {
63 };
64
65 /// Human readable name of an intent, for logging.
66 const char* ToString(Intent intent);
67
69 {
70 static const std::string Stopped;
71 static const std::string Running;
72 static const std::string Waiting;
73 static const std::string Mixed;
74 static const std::string Unknown;
75 static const std::string Inactive;
76 static const std::string Missing;
77
78 /**
79 * Combines the stati of several applications into the status of their common parent
80 * (a scenario or the package subtree of a scenario). The rules are:
81 *
82 * - `Missing` applications are ignored: a binary that cannot be found says nothing about
83 * what is currently running. If every application is missing, the result is `Missing`.
84 * - If any application is `Waiting`, the result is `Waiting`: a start/stop is in flight
85 * and that is the most useful thing to show.
86 * - `Unknown` applications are ignored as long as at least one other application has a
87 * definite status, so that a single indeterminate probe does not blank out a whole
88 * scenario. If all of them are `Unknown`, the result is `Unknown`.
89 * - If all remaining applications agree, that status is the result, otherwise `Mixed`.
90 *
91 * The result only depends on the set of stati, not on their order.
92 *
93 * Note that `Missing` is never stored on an ApplicationInstance itself; it is derived by
94 * the GUI from Application::getFound() and passed in here by the tree items.
95 */
96 static std::string Aggregate(const std::vector<std::string>& stati);
97 };
98
99 /**
100 * @class ApplicationInstance
101 * @ingroup Data_Structure
102 * @brief Class containing data about the instance of an application.
103 * Provides methods to get and set the data. It is only representative and doesn't actually synchronize
104 * with the configuration files.
105 */
107 public Application,
108 public std::enable_shared_from_this<ApplicationInstance>
109 {
110
111 private:
112 std::string instanceName;
113 std::filesystem::path configPath;
114 std::string status;
115 std::string nodeName;
116 std::string configDomain;
117 ScenarioPtr scenario;
118 /// Touched by the GUI thread, the status polling thread and every starter/stopper thread.
119 std::atomic<int> pid;
120 /// Published by the ApplicationLifecycle that owns this application, read by the GUI.
121 std::atomic<Intent> pendingIntent;
122 bool enabled;
123 bool readOnly;
124
125 public:
126 /**
127 * Constructor that sets the base data of this ApplicationInstance.
128 * @param executableName The name of the Application
129 * @param executablePath The path of the Executable
130 * @param instanceName a name that distinguishes this instance from other instances
131 * @param configPath path to the config file of this instance
132 */
133 ApplicationInstance(std::string executableName,
134 std::string executablePath,
135 std::string instanceName,
136 std::string configPath,
137 std::string packageName,
138 ScenarioPtr scenarioName,
139 std::string node,
140 bool enabled);
141
142 /**
143 * Constructor that sets the base data of this ApplicationInstance.
144 * @param application The application this class instantiates.
145 * @param instanceName a name that distinguishes this instance from other instances
146 * @param configPath path to the config file of this instance
147 */
149 std::string instanceName,
150 std::string configPath,
151 ScenarioPtr scenarioName,
152 std::string node,
153 bool enabled);
154
155 /**
156 * @return name of this ApplicationInstance
157 */
158 std::string getInstanceName();
159
160 /**
161 * Sets the name of this ApplicationInstance
162 * @param new name
163 */
164 void setInstanceName(std::string newName); //wird die setter gebraucht?
165
166 /**
167 * @return config path of this ApplicationInstance
168 */
169 std::string getConfigPath();
170 bool isConfigWritable();
171
173
174 /**
175 * Sets the config path of this ApplicationInstance
176 * @param new config path
177 */
178 void setConfigPath(std::string configPath);
179
180 /**
181 * @brief resetConfigPath. should be called when the instanceName is changed/ deletes the old cfg file and resets the local config Path to where the file should be
182 * you should call save after this
183 */
184 void resetConfigPath();
185
186 /**
187 * Returns the status. Doesn't update automatically, is not necessarily synchronized with
188 * the actual status of the process. Use the Executor to get the actual status of this application.
189 * @return status of this ApplicationInstance
190 * @see Executor
191 */
192 std::string getStatus();
193
194 /**
195 * Sets the status of this ApplicationInstance
196 * @param new status. Should be either "running" or "stopped" for Scenario statuses to work
197 * properly.
198 * @return tree if status changed.
199 */
200 bool setStatus(const std::string& status);
201
202 std::string getNodeName() const;
203 std::string getEffectiveNodeName() const;
204 void setNodeName(std::string nodeName);
205
206 /**
207 * @return pid of this ApplicationInstance
208 */
209 int getPid();
210
211 /**
212 * Sets the pid of this ApplicationInstance. This pid gets used by the Executor to
213 * stop this application, therefore it is not suggested to set this to random values.
214 * Set this to -1, if no pid is known.
215 * @param pid new pid
216 */
217 void setPid(int pid);
218
219 /**
220 * Sets the pid to -1, but only if it is still `expectedPid`.
221 *
222 * The status poller and the starter/stopper threads all inspect and update the pid
223 * concurrently. Whoever observes that a process has died must clear only the pid it
224 * actually probed - an unconditional reset can wipe the pid a concurrent start has just
225 * stored, which would leave a running application marked as stopped indefinitely.
226 *
227 * @return whether the pid was reset.
228 */
229 bool compareAndResetPid(int expectedPid);
230
231 /**
232 * Sets the pid to `newPid`, but only if no pid is currently known (i.e. it is -1).
233 * Used when adopting a pid cached on disk, so that a concurrently started process wins.
234 * @return whether the pid was set.
235 */
236 bool adoptPidIfUnset(int newPid);
237
238 /**
239 * Changes the value of the specified property.
240 * @param name name of the property whose value is to be changed
241 * @param value new value of the property
242 */
243 void modifyProperty(std::string name, std::string value);
244
245 /**
246 * Adds a new property with the specified name and value to this ApplicationInstance.
247 * @param name name of the new property
248 * @param value value of the new property
249 */
250 void addProperty(std::string name, std::string value);
251
252
253 /**
254 * Saves the IceProperties to the configPath
255 */
256 void save();
257
258 /**
259 * Make a local copy of this instance if it is linked and nothing otherwise
260 */
261 void makeLocal();
262
263 /**
264 * @brief linkFrom Link this instance configuration from the other instance.
265 * @param other the source instance
266 */
267 void linkFrom(ApplicationInstance& other);
268
269 /**
270 * @brief copyFrom Copy the other instance configuration to this one.
271 * @param other the instance to copy
272 */
273 void copyFrom(ApplicationInstance& other);
274
275 void deleteConfig();
276
277 /**
278 * Loades the IceProperties from the configPath
279 * Firstload determins if properties that equal their default value get uncommented
280 */
281 void load(bool firstLoad = false);
282
283 /**
284 * The intent this application is currently moving towards, or None when idle.
285 *
286 * Written by the ApplicationLifecycle that owns the application, so it is up to date as
287 * soon as a request has been made rather than only after the next status poll. The GUI uses
288 * it both to show the application as "Waiting" and to grey out the button of the operation
289 * that is under way.
290 */
291 Intent getPendingIntent() const;
292 void setPendingIntent(Intent intent);
293
294
295 bool getEnabled();
296 void setEnabled(bool enabled);
297
298 std::string getConfigDomain() const;
299 void setConfigDomain(const std::string& value);
300
301 bool isReadOnly() const;
302 };
303} // namespace ScenarioManager::Data_Structure
Class containing data about the instance of an application.
ApplicationInstance(std::string executableName, std::string executablePath, std::string instanceName, std::string configPath, std::string packageName, ScenarioPtr scenarioName, std::string node, bool enabled)
Constructor that sets the base data of this ApplicationInstance.
void setInstanceName(std::string newName)
Sets the name of this ApplicationInstance.
void setPid(int pid)
Sets the pid of this ApplicationInstance.
void addProperty(std::string name, std::string value)
Adds a new property with the specified name and value to this ApplicationInstance.
void setConfigPath(std::string configPath)
Sets the config path of this ApplicationInstance.
bool adoptPidIfUnset(int newPid)
Sets the pid to newPid, but only if no pid is currently known (i.e.
Intent getPendingIntent() const
The intent this application is currently moving towards, or None when idle.
void modifyProperty(std::string name, std::string value)
Changes the value of the specified property.
void makeLocal()
Make a local copy of this instance if it is linked and nothing otherwise.
void save()
Saves the IceProperties to the configPath.
void copyFrom(ApplicationInstance &other)
copyFrom Copy the other instance configuration to this one.
void linkFrom(ApplicationInstance &other)
linkFrom Link this instance configuration from the other instance.
bool compareAndResetPid(int expectedPid)
Sets the pid to -1, but only if it is still expectedPid.
void load(bool firstLoad=false)
Loades the IceProperties from the configPath Firstload determins if properties that equal their defau...
bool setStatus(const std::string &status)
Sets the status of this ApplicationInstance.
Application(std::string name, std::string executablePath, std::string packageName)
Constructor that sets the name and the path to the executable of the application.
std::shared_ptr< Scenario > ScenarioPtr
Definition Scenario.h:35
Intent
What the ScenarioManager is currently trying to do with an application.
const char * ToString(Intent intent)
Human readable name of an intent, for logging.
std::weak_ptr< ApplicationInstance > ApplicationInstanceWPtr
std::shared_ptr< ApplicationInstance > ApplicationInstancePtr
std::shared_ptr< std::vector< ApplicationInstancePtr > > ApplicationInstanceVectorPtr
static std::string Aggregate(const std::vector< std::string > &stati)
Combines the stati of several applications into the status of their common parent (a scenario or the ...