userver: userver/ugrpc/server/service_component_base.hpp Source File
Loading...
Searching...
No Matches
service_component_base.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/ugrpc/server/service_component_base.hpp
4/// @brief @copybrief ugrpc::server::ServiceComponentBase
5
6#include <atomic>
7
8#include <userver/components/component_base.hpp>
9#include <userver/engine/task/task_processor_fwd.hpp>
10#include <userver/middlewares/runner.hpp>
11#include <userver/utils/box.hpp>
12#include <userver/yaml_config/fwd.hpp>
13
14#include <userver/ugrpc/server/middlewares/fwd.hpp>
15#include <userver/ugrpc/server/service_base.hpp>
16
17USERVER_NAMESPACE_BEGIN
18
19namespace ugrpc::server {
20
21class ServerComponent;
23class MiddlewareBase;
24struct ServiceInfo;
25
26namespace impl {
27
28/// @brief The interface for a `ServerComponentBase` component. So, `ServerComponentBase` runs with middlewares.
29using MiddlewareRunnerComponentBase = USERVER_NAMESPACE::middlewares::RunnerComponentBase<MiddlewareBase, ServiceInfo>;
30
31} // namespace impl
32
33/// @ingroup userver_components userver_base_classes
34///
35/// @brief Base class for all the gRPC service components.
36///
37/// ## Static options of ugrpc::server::ServiceComponentBase :
38/// @include{doc} scripts/docs/en/components_schema/grpc/src/ugrpc/server/service_component_base.md
39///
40/// Options inherited from @ref middlewares::RunnerComponentBase :
41/// @include{doc} scripts/docs/en/components_schema/core/src/middlewares/runner_component_base.md
42///
43/// Options inherited from @ref components::ComponentBase :
44/// @include{doc} scripts/docs/en/components_schema/core/src/components/impl/component_base.md
45class ServiceComponentBase : public impl::MiddlewareRunnerComponentBase {
46public:
47 ServiceComponentBase(const components::ComponentConfig& config, const components::ComponentContext& context);
48
49 ~ServiceComponentBase() override;
50
51 static yaml_config::Schema GetStaticConfigSchema();
52
53protected:
54 /// Derived classes must store the actual service class in a field and call
55 /// RegisterService with it
57
58 /// @overload
60
61private:
62 ServerComponent& server_;
63 ServiceConfig config_;
64 std::atomic<bool> registered_{false};
65 utils::Box<ServiceInfo> info_;
66};
67
68namespace impl {
69
70template <typename ServiceInterface>
71// NOLINTNEXTLINE(fuchsia-multiple-inheritance)
72class ServiceComponentBase : public server::ServiceComponentBase, public ServiceInterface {
73 static_assert(std::is_base_of_v<ServiceBase, ServiceInterface> || std::is_base_of_v<GenericServiceBase, ServiceInterface>);
74
75public:
76 ServiceComponentBase(const components::ComponentConfig& config, const components::ComponentContext& context)
77 : server::ServiceComponentBase(config, context),
78 ServiceInterface()
79 {
80 // At this point the derived class that implements ServiceInterface is not
81 // constructed yet. We rely on the implementation detail that the methods of
82 // ServiceInterface are never called right after RegisterService. Unless
83 // Server starts during the construction of this component (which is an
84 // error anyway), we should be fine.
85 RegisterService(*this);
86 }
87
88private:
89 using server::ServiceComponentBase::RegisterService;
90};
91
92} // namespace impl
93
94} // namespace ugrpc::server
95
96USERVER_NAMESPACE_END