|
13 | 13 | #include <userver/crypto/openssl.hpp> |
14 | 14 | #include <userver/dynamic_config/snapshot.hpp> |
15 | 15 | #include <userver/dynamic_config/value.hpp> |
| 16 | +#include <userver/engine/exception.hpp> |
| 17 | +#include <userver/engine/task/task_with_result.hpp> |
16 | 18 | #include <userver/formats/json/serialize.hpp> |
17 | 19 | #include <userver/fs/blocking/read.hpp> |
18 | 20 | #include <userver/logging/impl/mem_logger.hpp> |
@@ -183,6 +185,33 @@ ManagerConfig ParseManagerConfigAndSetupLogging( |
183 | 185 | } |
184 | 186 | } |
185 | 187 |
|
| 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 | + |
186 | 215 | void DoRun( |
187 | 216 | const PathOrConfig& config, |
188 | 217 | const std::optional<std::string>& config_vars_path, |
@@ -217,34 +246,28 @@ void DoRun( |
217 | 246 | PreheatStacktraceCollector(); |
218 | 247 | } |
219 | 248 |
|
220 | | - manager.emplace(std::make_unique<ManagerConfig>(std::move(manager_config)), start_time, component_list); |
221 | | - } catch (const std::exception& ex) { |
222 | | - LOG_ERROR() << "Loading failed: " << ex; |
223 | | - throw; |
224 | | - } |
| 249 | + manager.emplace(std::make_unique<ManagerConfig>(std::move(manager_config)), start_time); |
225 | 250 |
|
226 | | - if (run_mode == RunMode::kOnce) { |
227 | | - return; |
228 | | - } |
| 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); |
229 | 254 |
|
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"); |
| 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&) { |
247 | 267 | } |
| 268 | + } catch (const std::exception& ex) { |
| 269 | + LOG_ERROR() << "Loading failed: " << ex; |
| 270 | + throw; |
248 | 271 | } |
249 | 272 | } |
250 | 273 |
|
|
0 commit comments