Skip to content

Commit 1148ce6

Browse files
committed
bug core: revert "catch signals before component system is up and running"
1. Exceptions during startup are swallowed, causing the service to hang on start instead of shutting down 2. There is a potential data race in `manager.OnSignal` commit_hash:091ba960c3fe23b6dc4d2c25a70e6e1388e3ea4e
1 parent f5bca75 commit 1148ce6

File tree

10 files changed

+45
-202
lines changed

10 files changed

+45
-202
lines changed

.mapping.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -758,11 +758,6 @@
758758
"core/functional_tests/metrics/tests/conftest.py":"taxi/uservices/userver/core/functional_tests/metrics/tests/conftest.py",
759759
"core/functional_tests/metrics/tests/static/metrics_values.txt":"taxi/uservices/userver/core/functional_tests/metrics/tests/static/metrics_values.txt",
760760
"core/functional_tests/metrics/tests/test_metrics.py":"taxi/uservices/userver/core/functional_tests/metrics/tests/test_metrics.py",
761-
"core/functional_tests/signal_during_boot/CMakeLists.txt":"taxi/uservices/userver/core/functional_tests/signal_during_boot/CMakeLists.txt",
762-
"core/functional_tests/signal_during_boot/service.cpp":"taxi/uservices/userver/core/functional_tests/signal_during_boot/service.cpp",
763-
"core/functional_tests/signal_during_boot/static_config.yaml":"taxi/uservices/userver/core/functional_tests/signal_during_boot/static_config.yaml",
764-
"core/functional_tests/signal_during_boot/tests/conftest.py":"taxi/uservices/userver/core/functional_tests/signal_during_boot/tests/conftest.py",
765-
"core/functional_tests/signal_during_boot/tests/test_rotate_logs.py":"taxi/uservices/userver/core/functional_tests/signal_during_boot/tests/test_rotate_logs.py",
766761
"core/functional_tests/slow_start/CMakeLists.txt":"taxi/uservices/userver/core/functional_tests/slow_start/CMakeLists.txt",
767762
"core/functional_tests/slow_start/config_vars.yaml":"taxi/uservices/userver/core/functional_tests/slow_start/config_vars.yaml",
768763
"core/functional_tests/slow_start/secure_data.json":"taxi/uservices/userver/core/functional_tests/slow_start/secure_data.json",

core/functional_tests/CMakeLists.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}-static-service)
3535
add_subdirectory(slow_start)
3636
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}-slow-start)
3737

38-
add_subdirectory(signal_during_boot)
39-
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}-signal-during-boot)
40-
4138
add_subdirectory(tracing)
4239
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}-tracing)
4340

core/functional_tests/signal_during_boot/CMakeLists.txt

Lines changed: 0 additions & 6 deletions
This file was deleted.

core/functional_tests/signal_during_boot/service.cpp

Lines changed: 0 additions & 35 deletions
This file was deleted.

core/functional_tests/signal_during_boot/static_config.yaml

Lines changed: 0 additions & 21 deletions
This file was deleted.

core/functional_tests/signal_during_boot/tests/conftest.py

Lines changed: 0 additions & 1 deletion
This file was deleted.

core/functional_tests/signal_during_boot/tests/test_rotate_logs.py

Lines changed: 0 additions & 58 deletions
This file was deleted.

core/src/components/manager.cpp

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,11 @@ void Manager::TaskProcessorsStorage::WaitForAllTasksBlocking() const noexcept {
152152
}
153153
}
154154

155-
Manager::Manager(std::unique_ptr<ManagerConfig>&& config, std::chrono::steady_clock::time_point start_time)
155+
Manager::Manager(
156+
std::unique_ptr<ManagerConfig>&& config,
157+
std::chrono::steady_clock::time_point start_time,
158+
const ComponentList& component_list
159+
)
156160
: config_(std::move(config)),
157161
task_processors_storage_(std::make_shared<
158162
engine::impl::TaskProcessorPools>(config_->coro_pool, config_->event_thread_pool)),
@@ -215,18 +219,15 @@ Manager::Manager(std::unique_ptr<ManagerConfig>&& config, std::chrono::steady_cl
215219
}
216220

217221
default_task_processor_ = default_task_processor_it->second.get();
218-
}
222+
RunInCoro(*default_task_processor_, [this, &component_list]() { CreateComponentContext(component_list); });
219223

220-
engine::TaskWithResult<void> Manager::StartComponentSystem(const ComponentList& component_list) {
221-
return engine::CriticalAsyncNoSpan(*default_task_processor_, [this, &component_list]() {
222-
CreateComponentContext(component_list);
223-
if (!config_->disable_phdr_cache) {
224-
engine::impl::InitPhdrCache();
225-
}
226-
LOG_INFO()
227-
<< "Started components manager. All the components have started "
228-
"successfully.";
229-
});
224+
if (!config_->disable_phdr_cache) {
225+
engine::impl::InitPhdrCache();
226+
}
227+
228+
LOG_INFO()
229+
<< "Started components manager. All the components have started "
230+
"successfully.";
230231
}
231232

232233
Manager::~Manager() {
@@ -324,10 +325,6 @@ void Manager::CreateComponentContext(const ComponentList& component_list) {
324325
component_context_ = std::make_unique<impl::ComponentContextImpl>(*this, std::move(loading_components));
325326

326327
AddComponents(component_list);
327-
328-
LOG_INFO()
329-
<< "Started components manager. All the components have started "
330-
"successfully.";
331328
}
332329

333330
components::ComponentConfigMap Manager::MakeComponentConfigMap(const ComponentList& component_list) {

core/src/components/manager.hpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,9 @@
1414

1515
USERVER_NAMESPACE_BEGIN
1616

17-
namespace engine {
18-
template <typename T>
19-
class TaskWithResult;
20-
21-
namespace impl {
17+
namespace engine::impl {
2218
class TaskProcessorPools;
23-
} // namespace impl
24-
} // namespace engine
19+
} // namespace engine::impl
2520

2621
namespace os_signals {
2722
class ProcessorComponent;
@@ -43,10 +38,13 @@ using TaskProcessorsMap = utils::impl::TransparentMap<std::string, std::unique_p
4338
// to the outside world.
4439
class Manager final {
4540
public:
46-
Manager(std::unique_ptr<ManagerConfig>&& config, std::chrono::steady_clock::time_point start_time);
41+
Manager(
42+
std::unique_ptr<ManagerConfig>&& config,
43+
std::chrono::steady_clock::time_point start_time,
44+
const ComponentList& component_list
45+
);
4746
~Manager();
4847

49-
engine::TaskWithResult<void> StartComponentSystem(const ComponentList& component_list);
5048
const ManagerConfig& GetConfig() const;
5149
const std::shared_ptr<engine::impl::TaskProcessorPools>& GetTaskProcessorPools() const;
5250
const TaskProcessorsMap& GetTaskProcessorsMap() const;

core/src/components/run.cpp

Lines changed: 25 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313
#include <userver/crypto/openssl.hpp>
1414
#include <userver/dynamic_config/snapshot.hpp>
1515
#include <userver/dynamic_config/value.hpp>
16-
#include <userver/engine/exception.hpp>
17-
#include <userver/engine/task/task_with_result.hpp>
1816
#include <userver/formats/json/serialize.hpp>
1917
#include <userver/fs/blocking/read.hpp>
2018
#include <userver/logging/impl/mem_logger.hpp>
@@ -185,33 +183,6 @@ ManagerConfig ParseManagerConfigAndSetupLogging(
185183
}
186184
}
187185

188-
void CatchSignalsLoop(impl::Manager& manager, RunMode run_mode, utils::SignalCatcher& signal_catcher) noexcept {
189-
if (run_mode == RunMode::kOnce) {
190-
return;
191-
}
192-
193-
LOG_INFO() << "Starting to catch signals";
194-
for (;;) {
195-
auto signum = signal_catcher.Catch();
196-
if (signum == SIGTERM || signum == SIGQUIT) {
197-
break;
198-
} else if (signum == SIGINT) {
199-
if (IsTraced()) {
200-
// SIGINT is masked and cannot be used
201-
std::raise(SIGTRAP);
202-
} else {
203-
break;
204-
}
205-
} else if (signum == SIGUSR1 || signum == SIGUSR2) {
206-
LOG_INFO() << "Signal caught: " << utils::strsignal(signum);
207-
manager.OnSignal(signum);
208-
} else {
209-
LOG_WARNING() << "Got unexpected signal: " << signum << " (" << utils::strsignal(signum) << ')';
210-
UASSERT_MSG(false, "unexpected signal");
211-
}
212-
}
213-
}
214-
215186
void DoRun(
216187
const PathOrConfig& config,
217188
const std::optional<std::string>& config_vars_path,
@@ -246,29 +217,35 @@ void DoRun(
246217
PreheatStacktraceCollector();
247218
}
248219

249-
manager.emplace(std::make_unique<ManagerConfig>(std::move(manager_config)), start_time);
250-
251-
// Start component system in background.
252-
// POSIX signals can be already handled while component system is loading.
253-
auto start_components_task = manager->StartComponentSystem(component_list);
254-
255-
// The main event loop.
256-
// Other threads handle coroutines.
257-
CatchSignalsLoop(*manager, run_mode, signal_catcher);
258-
259-
if (run_mode == RunMode::kNormal) {
260-
start_components_task.RequestCancel();
261-
}
262-
263-
try {
264-
start_components_task.BlockingWait();
265-
start_components_task.Get();
266-
} catch (const engine::WaitInterruptedException&) {
267-
}
220+
manager.emplace(std::make_unique<ManagerConfig>(std::move(manager_config)), start_time, component_list);
268221
} catch (const std::exception& ex) {
269222
LOG_ERROR() << "Loading failed: " << ex;
270223
throw;
271224
}
225+
226+
if (run_mode == RunMode::kOnce) {
227+
return;
228+
}
229+
230+
for (;;) {
231+
auto signum = signal_catcher.Catch();
232+
if (signum == SIGTERM || signum == SIGQUIT) {
233+
break;
234+
} else if (signum == SIGINT) {
235+
if (IsTraced()) {
236+
// SIGINT is masked and cannot be used
237+
std::raise(SIGTRAP);
238+
} else {
239+
break;
240+
}
241+
} else if (signum == SIGUSR1 || signum == SIGUSR2) {
242+
LOG_INFO() << "Signal caught: " << utils::strsignal(signum);
243+
manager->OnSignal(signum);
244+
} else {
245+
LOG_WARNING() << "Got unexpected signal: " << signum << " (" << utils::strsignal(signum) << ')';
246+
UASSERT_MSG(false, "unexpected signal");
247+
}
248+
}
272249
}
273250

274251
} // namespace

0 commit comments

Comments
 (0)