lintel 0.2.0
Loading...
Searching...
No Matches
ProcessService.h
Go to the documentation of this file.
1#ifndef LINTEL_PROCESSSERVICE_H
2#define LINTEL_PROCESSSERVICE_H
3
4#include <atomic>
5#include <chrono>
6#include <condition_variable>
7#include <filesystem>
8#include <future>
9#include <memory>
10#include <mutex>
11#include <thread>
12
23
24#include <boost/process/v1/detail/config.hpp>
25
26// boost::process::v1 is an inline namespace only for BOOST_PROCESS_VERSION == 1 and a plain nested
27// namespace otherwise - see BOOST_PROCESS_V1_INLINE in boost/process/v1/detail/config.hpp. A
28// hardcoded "inline" here therefore only compiles while this header happens to be seen before any
29// boost/process header; the reverse order (which every consumer that spawns a process itself will
30// have) fails with "inline namespace must be specified at initial definition". config.hpp is the
31// cheap header that defines the macro, so forward declaring through it keeps the child type
32// incomplete - no boost/process/child.hpp in every translation unit that sees ProcessService.h.
33namespace boost::process {
34BOOST_PROCESS_V1_INLINE namespace v1 { class child; }
35}// namespace boost::process
36
37namespace lintel {
39class ProcessService : public PropertyRegistration<ProcessService>
40{
41private:
43 class ProcessExecutes
44 {
45 private:
46 // variables
47 std::shared_ptr<Process> m_process = nullptr;
48 std::shared_ptr<boost::process::v1::child> m_child;
49 std::shared_ptr<std::promise<int>> m_promise = nullptr;
50 // automation state
51 std::chrono::steady_clock::time_point m_processStartTime{};
52 std::chrono::steady_clock::time_point m_lastRestartTime{};
53 int m_consecutiveFailures = 0;
54 bool m_failed = false;
55 std::optional<ProcessResourceData> m_lastResourceSample;
56 std::chrono::steady_clock::time_point m_lastNotifyTime{};
57
58 public:
59 ProcessExecutes() = default;
60
63 void setProcess(std::shared_ptr<Process> process) { m_process = std::move(process); }
64
67 void setChild(std::shared_ptr<boost::process::v1::child> child)
68 {
69 m_child = std::move(child);
70 m_processStartTime = std::chrono::steady_clock::now();
71 }
72
75 [[nodiscard]] const std::shared_ptr<Process> &getProcess() const { return m_process; }
76
79 [[nodiscard]] std::shared_ptr<boost::process::v1::child> &getChild() { return m_child; }
80
83 void setPromiseValue(int exitCode)
84 {
85 if (m_promise == nullptr) { m_promise = std::make_shared<std::promise<int>>(); }
86 m_promise->set_value(exitCode);
87 }
88
91 void setPromiseException(const std::exception_ptr &p)
92 {
93 if (m_promise == nullptr) { m_promise = std::make_shared<std::promise<int>>(); }
94 m_promise->set_exception(p);
95 }
96
99 std::future<int> getFuture()
100 {
101 if (m_promise == nullptr) { m_promise = std::make_shared<std::promise<int>>(); }
102 return m_promise->get_future();
103 }
104
106 void markStart() { m_processStartTime = std::chrono::steady_clock::now(); }
107
109 [[nodiscard]] std::chrono::steady_clock::time_point processStartTime() const { return m_processStartTime; }
110
112 void markRestart() { m_lastRestartTime = std::chrono::steady_clock::now(); }
113
115 [[nodiscard]] std::chrono::steady_clock::time_point lastRestartTime() const { return m_lastRestartTime; }
116
118 void setConsecutiveFailures(int failures) { m_consecutiveFailures = failures; }
119
121 [[nodiscard]] int consecutiveFailures() const { return m_consecutiveFailures; }
122
124 void setFailed(bool failed) { m_failed = failed; }
125
127 [[nodiscard]] bool isFailed() const { return m_failed; }
128
130 void setResourceSample(ProcessResourceData sample) { m_lastResourceSample = sample; }
131
133 [[nodiscard]] const std::optional<ProcessResourceData> &resourceSample() const { return m_lastResourceSample; }
134
136 void setLastNotifyTime(std::chrono::steady_clock::time_point time) { m_lastNotifyTime = time; }
137
139 [[nodiscard]] std::chrono::steady_clock::time_point lastNotifyTime() const { return m_lastNotifyTime; }
140 };
141
142 // injections
143 std::shared_ptr<ProcessName> m_processName;
144 std::shared_ptr<EnvironmentConfiguration> m_environmentConfiguration;
145 std::shared_ptr<Process> m_process;
146 std::shared_ptr<Configuration> m_configuration;
147 std::shared_ptr<IHistoryService> m_historyService;
148 // variables
149 std::mutex m_processesMutex;
150 std::map<std::string, ProcessExecutes> m_processes;
151 std::mutex m_processGroupMutex;
152 std::map<std::string, std::shared_ptr<ProcessGroup>> m_processGroups;
153 std::thread m_monitorThread;
154 std::atomic_bool m_running = true;
155 std::condition_variable m_condition;
156 std::mutex m_mutex;
157 // properties
158 std::shared_ptr<Property<std::chrono::seconds>> m_monitorWaitTime;
159 std::shared_ptr<Property<std::chrono::milliseconds>> m_processStopWaitTime;
160
161 void run();
162
163 void monitorProcess();
164
165 void monitorProcessGroups();
166
170 std::filesystem::path resolvePath(const std::filesystem::path &path) const;
171
177 std::shared_ptr<boost::process::v1::child>
178 spawnChild(const std::filesystem::path &path, const std::vector<std::string> &args, const std::string &configName);
179
184 void sampleResources(const std::string &id, ProcessExecutes &processExecutes);
185
190 void refreshResourceSampleIfStale(ProcessExecutes &processExecutes);
191
197 ProcessInfo processInfoOf(const std::string &id,
198 ProcessExecutes &processExecutes,
199 const std::string &groupName,
200 const std::string &groupId);
201
202public:
208 ProcessService(std::shared_ptr<ProcessName> processName,
209 std::shared_ptr<EnvironmentConfiguration> environmentConfiguration,
210 std::shared_ptr<Configuration> configuration,
211 std::shared_ptr<IHistoryService> historyService);
212
213 ~ProcessService() override;
214
215 // Process Information
219 std::vector<ProcessGroupDto> allGroupsOf(const std::string &name);
220
223 std::vector<ProcessInfo> allActiveOf();
224
228
232 std::optional<std::shared_ptr<Process>> of(const std::string &id);
233
234 // Process operations
238 std::optional<std::future<int>> startOf(const Process &process);
239
242 void restartOf(const Process &process);
243
247 bool stopOf(const Process &process);
248
251 void terminateOf(const Process &process);
252
255 void detachOf(const Process &process);
256
259 void resetOf(const Process &process);
260
261 // Process group operations
265
269
274
278
282
286
288
289 void onInitialize() override;
290};
291
292}// namespace lintel
293#endif// LINTEL_PROCESSSERVICE_H
Definition ProcessGroup.h:13
Definition ProcessInfo.h:13
Definition ProcessService.h:40
ProcessInfo currentOf()
void resetOf(const Process &process)
void detachOf(const Process &process)
ShutdownPriority shutdownPriorityOf() const override
Definition ProcessService.h:287
bool stopOf(const ProcessGroup &processGroup)
void terminateOf(const Process &process)
void onInitialize() override
ProcessService(std::shared_ptr< ProcessName > processName, std::shared_ptr< EnvironmentConfiguration > environmentConfiguration, std::shared_ptr< Configuration > configuration, std::shared_ptr< IHistoryService > historyService)
bool stopOf(const Process &process)
std::vector< ProcessInfo > allActiveOf()
std::optional< std::shared_ptr< Process > > of(const std::string &id)
void detachOf(const ProcessGroup &processGroup)
~ProcessService() override
void terminateOf(const ProcessGroup &processGroup)
void restartOf(const Process &process)
std::optional< std::future< int > > startOf(const Process &process)
void startOf(const ProcessGroup &processGroup)
void restartOf(const ProcessGroup &processGroup)
std::vector< ProcessGroupDto > allGroupsOf(const std::string &name)
Definition Process.h:21
Definition PropertyRegistration.h:14
Definition ProcessService.h:33
Definition BaseFeature.h:6
ShutdownPriority
Definition ShutdownPriority.h:8
@ PROCESS_SERVICE
Definition ShutdownPriority.h:10
constexpr std::string_view type_name()
Definition TypeName.h:9
Definition ProcessResourceReader.h:17