userver: userver/ugrpc/server/service_component_base.hpp Source File
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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/yaml_config/fwd.hpp>
12
13#include <userver/ugrpc/server/middlewares/base.hpp>
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;
23
24namespace impl {
25
26/// @brief The interface for a `ServerComponentBase` component. So, `ServerComponentBase` runs with middlewares.
27using MiddlewareRunner =
28 USERVER_NAMESPACE::middlewares::RunnerComponentBase<MiddlewareBase, ugrpc::server::ServiceInfo>;
29
30} // namespace impl
31
32// clang-format off
33
34/// @ingroup userver_components userver_base_classes
35///
36/// @brief Base class for all the gRPC service components.
37///
38/// ## Static options:
39/// Name | Description | Default value
40/// ---- | ----------- | -------------
41/// task-processor | the task processor to use for responses | taken from grpc-server.service-defaults
42/// disable-user-pipeline-middlewares | flag to disable `groups::User` middlewares from pipeline | false
43/// disable-all-pipeline-middlewares | flag to disable all middlewares from pipline | false
44/// middlewares | middlewares names to use | `{}` (use server defaults)
45
46// clang-format on
47
49public:
50 ServiceComponentBase(const components::ComponentConfig& config, const components::ComponentContext& context);
51
52 static yaml_config::Schema GetStaticConfigSchema();
53
54protected:
55 /// Derived classes must store the actual service class in a field and call
56 /// RegisterService with it
58
59 /// @overload
61
62private:
63 ServerComponent& server_;
64 ServiceConfig config_;
65 std::atomic<bool> registered_{false};
66 ServiceInfo info_{};
67};
68
69namespace impl {
70
71template <typename ServiceInterface>
72// NOLINTNEXTLINE(fuchsia-multiple-inheritance)
73class ServiceComponentBase : public server::ServiceComponentBase, public ServiceInterface {
74 static_assert(std::is_base_of_v<ServiceBase, ServiceInterface> || std::is_base_of_v<GenericServiceBase, ServiceInterface>);
75
76public:
77 ServiceComponentBase(const components::ComponentConfig& config, const components::ComponentContext& context)
78 : server::ServiceComponentBase(config, context), ServiceInterface() {
79 // At this point the derived class that implements ServiceInterface is not
80 // constructed yet. We rely on the implementation detail that the methods of
81 // ServiceInterface are never called right after RegisterService. Unless
82 // Server starts during the construction of this component (which is an
83 // error anyway), we should be fine.
84 RegisterService(*this);
85 }
86
87private:
88 using server::ServiceComponentBase::RegisterService;
89};
90
91} // namespace impl
92
93} // namespace ugrpc::server
94
95USERVER_NAMESPACE_END