userver: userver/components/state.hpp Source File
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
state.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/components/state.hpp
4/// @brief @copybrief components::State
5
6#include <string_view>
7#include <unordered_set>
8
9USERVER_NAMESPACE_BEGIN
10
11namespace components {
12
13class ComponentContext;
14
15namespace impl {
16class ComponentContextImpl;
17}
18
19// clang-format off
20/// @brief All components pass through these stages during the service lifetime.
21/// @see @ref scripts/docs/en/userver/component_system.md
22///
23/// @dot
24/// digraph ServiceLifetimeStages {
25/// node [shape=record];
26///
27/// kLoading [label="{kLoading | <f0> * Components are constructed }"];
28/// kOnAllComponentsLoadedIsRunning [label="{kOnAllComponentsLoadedIsRunning | <f1> * OnAllComponentsLoaded is called }"];
29/// kRunning [label="{kRunning | <f2> * All components loaded successfully \n * Service is fully operational }"];
30/// kGracefulShutdown [label="{kGracefulShutdown | <f3> * Waits graceful_shutdown_interval }"];
31/// kOnAllComponentsAreStoppingIsRunning [label="{kOnAllComponentsAreStoppingIsRunning | <f4> * OnAllComponentsAreStopping is called \n * Reverse-dependency order }"];
32/// kStopping [label="{kStopping | <f5> * Components are destroyed \n * Reverse-dependency order }"];
33///
34/// kLoading -> kOnAllComponentsLoadedIsRunning;
35/// kLoading -> kOnAllComponentsAreStoppingIsRunning [label=" Exception during construction "];
36/// kOnAllComponentsLoadedIsRunning -> kRunning;
37/// kOnAllComponentsLoadedIsRunning -> kOnAllComponentsAreStoppingIsRunning [label=" OnAllComponentsLoaded throws "];
38/// kRunning -> kGracefulShutdown [label=" Received SIGINT or SIGTERM "];
39/// kGracefulShutdown -> kOnAllComponentsAreStoppingIsRunning;
40/// kOnAllComponentsAreStoppingIsRunning -> kStopping;
41/// }
42/// @enddot
43// clang-format on
45 /// Constructors are running for all registered components. Components can depend on each other at this stage
46 /// by calling @ref components::ComponentContext::FindComponent and friends.
47 ///
48 /// If any component throws an exception, then the service transitions
49 /// into @ref ServiceLifetimeStage::kOnAllComponentsAreStoppingIsRunning stage.
51
52 /// @ref components::ComponentBase::OnAllComponentsLoaded (noop by default) is running for all components.
53 /// This stage starts after constructors for all components have completed without an exception.
54 ///
55 /// The order of `OnAllComponentsLoaded` hooks invocations respects the order of components defined
56 /// at @ref ServiceLifetimeStage::kComponentsLoading stage.
58
59 /// This stage marks that all `OnAllComponentsLoaded` hooks (as described
60 /// in @ref ServiceLifetimeStage::kOnAllComponentsLoadedIsRunning) have completed
61 /// successfully (without an exception). At this point the service is fully running.
62 ///
63 /// This stage ends once the service receives a shutdown signal (`SIGINT` or `SIGTERM`).
65
66 /// The service waits for `graceful_shutdown_interval` (0 by default) before continuing with the actual service
67 /// shutdown in @ref ServiceLifetimeStage::kOnAllComponentsAreStoppingIsRunning.
68 ///
69 /// @see @ref components::ManagerControllerComponent
70 ///
71 /// Example:
72 /// @snippet core/functional_tests/graceful_shutdown/static_config.yaml graceful_shutdown_interval
74
75 /// @ref components::ComponentBase::OnAllComponentsAreStopping (noop by default) is running for all components.
76 /// This stage starts once the service has received a shutdown signal (see @ref ServiceLifetimeStage::kRunning) and
77 /// @ref ServiceLifetimeStage::kGracefulShutdown stage (if any) has completed.
78 ///
79 /// If an error occurs during service startup, then `OnAllComponentsAreStopping` runs after
80 /// @ref components::ComponentBase::OnLoadingCancelled for all constructed components.
81 ///
82 /// The order of `OnAllComponentsAreStopping` hooks invocations respects the order of components defined
83 /// at @ref ServiceLifetimeStage::kComponentsLoading stage (they run in the reverse-dependency order).
85
86 /// Destructors are running for all components. This stage starts once
87 /// @ref ServiceLifetimeStage::kOnAllComponentsAreStoppingIsRunning stage.
88 ///
89 /// If an error occurs during service startup, then destructors run
90 /// after @ref ServiceLifetimeStage::kOnAllComponentsAreStoppingIsRunning for all constructed components.
91 ///
92 /// The order of destructor invocations respects the order of components defined
93 /// at @ref ServiceLifetimeStage::kComponentsLoading stage (they run in the reverse-dependency order).
95};
96
97/// Converts a @ref components::ServiceLifetimeStage to debug string for logging.
99
100/// A view of the components' state that is usable after the components are
101/// constructed and until all the components are destroyed.
102///
103/// @see components::ComponentContext
104class State final {
105public:
106 explicit State(const ComponentContext& cc) noexcept;
107
108 /// @returns true if one of the components is in fatal state and can not
109 /// work. A component is in fatal state if the
110 /// components::ComponentHealth::kFatal value is returned from the overridden
111 /// components::ComponentBase::GetComponentHealth().
113
114 /// @returns the current service lifetime stage.
115 /// @see @ref components::ServiceLifetimeStage
117
118 /// @returns true if component with name `component_name` depends
119 /// (directly or transitively) on a component with name `dependency`.
120 ///
121 /// Component with name `component_name` should be loaded.
122 /// Components construction should finish before any call to this function
123 /// is made.
124 ///
125 /// Note that GetAllDependencies usually is more effective, if you are
126 /// planning multiple calls for the same component name.
127 bool HasDependencyOn(std::string_view component_name, std::string_view dependency) const;
128
129 /// @returns all the components that `component_name` depends on directly or
130 /// transitively.
131 ///
132 /// Component with name `component_name` should be loaded.
133 /// Components construction should finish before any call to this function
134 /// is made. The result should now outlive the all the components
135 /// destruction.
136 std::unordered_set<std::string_view> GetAllDependencies(std::string_view component_name) const;
137
138private:
139 const impl::ComponentContextImpl& impl_;
140};
141
142} // namespace components
143
144USERVER_NAMESPACE_END