Skip to content

Commit 0d56bee

Browse files
authored
Merge pull request #55 from Valeo-S-CORE-Organization/Implement_report_running_state
Implementing report running state in lifecycle manager
2 parents 6b65643 + 2b0f7bb commit 0d56bee

6 files changed

Lines changed: 117 additions & 72 deletions

File tree

examples/cpp_lifecycle_app/BUILD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ cc_binary(
2525
}),
2626
visibility = ["//visibility:public"],
2727
deps = [
28-
"//src/launch_manager_daemon/lifecycle_client_lib:lifecycle_client",
28+
"//src/lifecycle_client_lib",
2929
],
3030
)

examples/cpp_lifecycle_app/main.cpp

Lines changed: 100 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,19 @@
1313

1414
#include <optional>
1515
#include <unistd.h>
16-
#include <csignal>
17-
#include <atomic>
18-
#include <thread>
1916
#include <iostream>
2017
#include <ctime>
2118
#include <string>
19+
#include <chrono>
20+
#include <vector>
2221

2322
#ifdef __linux__
2423
#include <linux/prctl.h>
2524
#include <sys/prctl.h>
2625
#endif
2726

28-
#include "score/lcm/lifecycle_client.h"
27+
#include "src/lifecycle_client_lib/include/application.h"
28+
#include "src/lifecycle_client_lib/include/runapplication.h"
2929

3030
/// @brief CLI configuration options for the not_supervised_application process
3131
struct Config
@@ -53,18 +53,15 @@ std::optional<Config> parseOptions(int argc, char *const *argv) noexcept
5353
switch (static_cast<char>(c))
5454
{
5555
case 'r':
56-
// response time
5756
config.responseTimeInMs = std::stoi(optarg);
5857
break;
5958

6059
case 'c':
61-
// crash time
6260
config.crashRequested = true;
6361
config.crashTimeInMs = std::stoi(optarg);
6462
break;
6563

6664
case 's':
67-
// start-up failure
6865
config.failToStart = true;
6966
break;
7067

@@ -88,93 +85,128 @@ std::optional<Config> parseOptions(int argc, char *const *argv) noexcept
8885
return config;
8986
}
9087

91-
std::atomic<bool> exitRequested{false};
92-
93-
void signalHandler(int)
88+
void set_process_name()
9489
{
95-
exitRequested = true;
96-
}
97-
98-
void set_process_name() {
9990
const char* identifier = getenv("PROCESSIDENTIFIER");
100-
if(identifier != nullptr) {
91+
if (identifier != nullptr)
92+
{
10193
#ifdef __QNXNTO__
102-
if (pthread_setname_np(pthread_self(), identifier) != 0) {
103-
std::cerr << "Failed to set QNX thread name" << std::endl;
104-
}
94+
if (pthread_setname_np(pthread_self(), identifier) != 0)
95+
{
96+
std::cerr << "Failed to set QNX thread name" << std::endl;
97+
}
10598
#elif defined(__linux__)
106-
if (prctl(PR_SET_NAME, identifier) < 0) {
107-
std::cerr << "Failed to set process name to " << identifier << std::endl;
108-
}
99+
if (prctl(PR_SET_NAME, identifier) < 0)
100+
{
101+
std::cerr << "Failed to set process name to " << identifier << std::endl;
102+
}
109103
#endif
110104
}
111105
}
112106

113-
int main(int argc, char **argv)
107+
class LifecycleApp final : public score::mw::lifecycle::Application
114108
{
115-
set_process_name();
109+
public:
110+
std::int32_t Initialize(const score::mw::lifecycle::ApplicationContext& appCtx) override
111+
{
112+
set_process_name();
116113

117-
signal(SIGINT, signalHandler);
118-
signal(SIGTERM, signalHandler);
114+
// Build a classic argv for getopt() from ApplicationContext arguments
115+
const auto& args = appCtx.get_arguments();
116+
m_argvStorage.clear();
117+
m_argvStorage.reserve(args.size() + 2);
119118

120-
const auto config = parseOptions(argc, argv);
121-
if (!config)
122-
{
123-
return EXIT_FAILURE;
124-
}
119+
// Ensure argv[0] exists (getopt expects it)
120+
if (args.empty())
121+
{
122+
m_argvStorage.push_back(const_cast<char*>("LifecycleApp"));
123+
}
124+
else
125+
{
126+
for (const auto& s : args)
127+
{
128+
// NOTE: relies on the underlying storage staying alive during Initialize().
129+
m_argvStorage.push_back(const_cast<char*>(s.data()));
130+
}
131+
}
125132

126-
std::chrono::time_point<std::chrono::steady_clock> startTime = std::chrono::steady_clock::now();
127-
std::chrono::duration<double, std::milli> runTime;
133+
m_argvStorage.push_back(nullptr);
128134

129-
if (true == config->failToStart)
130-
{
131-
return EXIT_FAILURE;
132-
}
135+
optind = 1;
133136

134-
score::lcm::LifecycleClient{}.ReportExecutionState(score::lcm::ExecutionState::kRunning);
137+
const int argcLocal = static_cast<int>(m_argvStorage.size() - 1);
138+
const auto config = parseOptions(argcLocal, m_argvStorage.data());
139+
if (!config)
140+
{
141+
return EXIT_FAILURE;
142+
}
135143

136-
timespec req{
137-
static_cast<time_t>(config->responseTimeInMs / 1000),
138-
static_cast<long>((config->responseTimeInMs % 1000) * 1000000L)
139-
};
140-
auto timeLastVerboseLog = std::chrono::steady_clock::now();
141-
while (!exitRequested)
142-
{
143-
if (true == config->crashRequested)
144+
m_config = *config;
145+
146+
if (true == m_config.failToStart)
144147
{
145-
runTime = std::chrono::steady_clock::now() - startTime;
148+
return EXIT_FAILURE;
149+
}
146150

147-
int timeTillCrash = static_cast<int>(config->crashTimeInMs - runTime.count());
151+
return 0;
152+
}
148153

149-
if (timeTillCrash < config->responseTimeInMs)
154+
std::int32_t Run(const score::cpp::stop_token& stopToken) override
155+
{
156+
std::chrono::time_point<std::chrono::steady_clock> startTime = std::chrono::steady_clock::now();
157+
std::chrono::duration<double, std::milli> runTime;
158+
159+
timespec req{
160+
static_cast<time_t>(m_config.responseTimeInMs / 1000),
161+
static_cast<long>((m_config.responseTimeInMs % 1000) * 1000000L)
162+
};
163+
164+
auto timeLastVerboseLog = std::chrono::steady_clock::now();
165+
166+
while (!stopToken.stop_requested())
167+
{
168+
if (true == m_config.crashRequested)
150169
{
151-
// OK we need a shorter sleep now
152-
if (timeTillCrash > 0)
170+
runTime = std::chrono::steady_clock::now() - startTime;
171+
int timeTillCrash = static_cast<int>(m_config.crashTimeInMs - runTime.count());
172+
173+
if (timeTillCrash < m_config.responseTimeInMs)
153174
{
154-
timespec crash_req{
155-
static_cast<time_t>(timeTillCrash / 1000),
156-
static_cast<long>((timeTillCrash % 1000) * 1000000L)
157-
};
158-
nanosleep(&crash_req, nullptr);
175+
if (timeTillCrash > 0)
176+
{
177+
timespec crash_req{
178+
static_cast<time_t>(timeTillCrash / 1000),
179+
static_cast<long>((timeTillCrash % 1000) * 1000000L)
180+
};
181+
nanosleep(&crash_req, nullptr);
182+
}
183+
184+
std::abort();
159185
}
160-
161-
// let's crash...
162-
std::abort();
163186
}
164-
}
165-
166187

167-
if(config->verbose) {
168-
const auto now = std::chrono::steady_clock::now();
169-
if(now - timeLastVerboseLog >= std::chrono::seconds(1)) {
170-
std::cout << "LifecycleApp: " << "Running in verbose mode" << std::endl;
171-
timeLastVerboseLog = now;
188+
if (m_config.verbose)
189+
{
190+
const auto now = std::chrono::steady_clock::now();
191+
if (now - timeLastVerboseLog >= std::chrono::seconds(1))
192+
{
193+
std::cout << "LifecycleApp: Running in verbose mode" << std::endl;
194+
timeLastVerboseLog = now;
195+
}
172196
}
197+
198+
nanosleep(&req, nullptr);
173199
}
174200

175-
nanosleep(&req, nullptr);
201+
return EXIT_SUCCESS;
176202
}
177203

178-
// normal exit
179-
return EXIT_SUCCESS;
204+
private:
205+
Config m_config{};
206+
std::vector<char*> m_argvStorage{};
207+
};
208+
209+
int main(int argc, char** argv)
210+
{
211+
return score::mw::lifecycle::run_application<LifecycleApp>(argc, argv);
180212
}

src/lifecycle_client_lib/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ cc_library(
4444
}),
4545
visibility = ["//visibility:public"],
4646
deps = [
47+
"//src/launch_manager_daemon/lifecycle_client_lib:lifecycle_client",
4748
"@score_baselibs//score/language/futurecpp",
4849
"@score_baselibs//score/memory:string_literal",
4950
"@score_baselibs//score/mw/log",
@@ -115,6 +116,7 @@ cc_library(
115116
tags = ["FUSA"],
116117
deps = [
117118
":application",
119+
"//src/launch_manager_daemon/lifecycle_client_lib:lifecycle_client",
118120
"@score_baselibs//score/mw/log",
119121
"@score_baselibs//score/os:stdlib",
120122
"@score_baselibs//score/os/utils:signal",

src/lifecycle_client_lib/include/lifecyclemanager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class LifeCycleManager
8383
/**
8484
* \brief Hook function for reporting running state.
8585
*/
86-
virtual void report_running() noexcept {};
86+
virtual void report_running() noexcept ;
8787
/**
8888
* \brief Hook function for reporting shutdown state.
8989
*/

src/lifecycle_client_lib/include/runapplication.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ template <typename ApplicationType, typename... Args>
6868
/* NOLINTNEXTLINE(modernize-avoid-c-arrays): array tolerated for command line arguments */
6969
std::int32_t run_application(const std::int32_t argc, const score::StringLiteral argv[], Args&&... args)
7070
{
71-
return 0;
71+
score::mw::lifecycle::Run<ApplicationType> runner(argc, argv);
72+
return runner.AsPosixProcess(std::forward<Args>(args)...);
7273
}
7374

7475
} // namespace lifecycle

src/lifecycle_client_lib/src/lifecyclemanager.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
#include "score/os/errno.h"
1717
#include <cstdlib>
18-
18+
#include "score/lcm/lifecycle_client.h"
1919
#include "score/mw/log/logging.h"
2020
#include "score/os/stdlib_impl.h"
2121

@@ -166,3 +166,13 @@ void score::mw::lifecycle::LifeCycleManager::handle_signal()
166166
/* KW_SUPPRESS_END:MISRA.STDLIB.ABORT,MISRA.USE.EXPANSION */
167167
}
168168
}
169+
170+
void score::mw::lifecycle::LifeCycleManager::report_running() noexcept
171+
{
172+
mw::log::LogInfo() << "Reporting kRunning to Launch Manager";
173+
const auto result = score::lcm::LifecycleClient{}.ReportExecutionState(score::lcm::ExecutionState::kRunning);
174+
if (!result.has_value())
175+
{
176+
mw::log::LogError() << "Failed to report kRunning to Launch Manager: " << result.error().Message();
177+
}
178+
}

0 commit comments

Comments
 (0)