userver: userver/storages/postgres/component.hpp Source File
Loading...
Searching...
No Matches
component.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/postgres/component.hpp
4/// @brief @copybrief components::Postgres
5
6#include <chrono>
7
8#include <userver/components/component_base.hpp>
9#include <userver/concurrent/async_event_source.hpp>
10#include <userver/dynamic_config/snapshot.hpp>
11#include <userver/engine/mutex.hpp>
12#include <userver/storages/secdist/secdist.hpp>
13#include <userver/utils/statistics/entry.hpp>
14
15#include <userver/storages/postgres/database.hpp>
16
17USERVER_NAMESPACE_BEGIN
18
19namespace components {
20
21/// @ingroup userver_components
22///
23/// @brief PosgreSQL client component
24///
25/// Provides access to a PostgreSQL cluster.
26///
27/// ## Dynamic options:
28/// * @ref POSTGRES_DEFAULT_COMMAND_CONTROL
29/// * @ref POSTGRES_HANDLERS_COMMAND_CONTROL
30/// * @ref POSTGRES_QUERIES_COMMAND_CONTROL
31/// * @ref POSTGRES_CONNECTION_POOL_SETTINGS
32/// * @ref POSTGRES_TOPOLOGY_SETTINGS
33/// * @ref POSTGRES_CONNECTION_SETTINGS
34/// * @ref POSTGRES_STATEMENT_METRICS_SETTINGS
35/// * @ref POSTGRES_CONNLIMIT_MODE_AUTO_ENABLED
36///
37/// ## Static configuration example:
38///
39/// ```
40/// # yaml
41/// postgres-taxi:
42/// dbalias: taxi
43/// blocking_task_processor: task-processor-name
44/// max_replication_lag: 60s
45/// min_pool_size: 4
46/// max_pool_size: 15
47/// max_queue_size: 200
48/// max_statement_metrics: 50
49/// ```
50/// You must specify either `dbalias` or `dbconnection`.
51/// If the component is configured with an alias, it will lookup connection data
52/// in Secdist.
53///
54/// It is a common practice to provide a database connection string via
55/// environment variables. To retrieve a value from the environment use
56/// `dbconnection#env: THE_ENV_VARIABLE_WITH_CONNECTION_STRING` as described
57/// in yaml_config::YamlConfig.
58///
59/// You must specify `blocking_task_processor` as well.
60///
61/// `max_replication_lag` can be used to tune replication lag limit for replicas.
62/// Once the replica lag exceeds this value it will be automatically disabled.
63/// Note, however, that client-size lag detection is not precise in nature
64/// and can only provide the precision of couple seconds.
65///
66/// ## Secdist format
67///
68/// A PosgreSQL alias in secdist is described as a JSON array of objects
69/// containing a single cluster description. There are two formats of describing
70/// a cluster, the first one assigns predefined roles to DSNs, the second one
71/// is just a list of DSNs and the Postgres component takes care of discovering
72/// the cluster's topology itself.
73///
74/// Note that if the `dbalias` option is provided and components::Secdist component has `update-period` other
75/// than 0, then new connections are created or gracefully closed as the secdist configuration change to new value.
76///
77/// ### Predefined roles
78///
79/// In predefined roles format the component requires single-host connection
80/// strings.
81///
82/// ```json
83/// {
84/// "shard_number" : 0,
85/// "master": "host=localhost dbname=example",
86/// "sync_slave": "host=localhost dbname=example",
87/// "slaves": [
88/// "host=localhost dbname=example"
89/// ]
90/// }
91/// ```
92///
93/// The predefined roles format is deprecated and the support will be removed
94/// soon.
95///
96/// ### Automatic discovery
97///
98/// In automatic discovery format the connection strings are any valid
99/// PostgreSQL connection strings including multi-host ones with the exception
100/// of `target_session_attrs` which will be ignored.
101///
102/// ```json
103/// {
104/// "shard_number" : 0,
105/// "hosts": [
106/// "host=host1,host2,host3 dbname=example",
107/// "postgresql://host1:5432,host2:6432,host3:12000/example"
108/// ]
109/// }
110/// ```
111///
112/// The `shard_number` parameter is required in both formats and must match the
113/// index of cluster description object in the alias array.
114///
115/// Please see [PostgreSQL documentation](https://www.postgresql.org/docs/12/libpq-connect.html#LIBPQ-CONNSTRING)
116/// on connection strings.
117///
118/// ## Static options of components::Postgres :
119/// @include{doc} scripts/docs/en/components_schema/postgresql/src/storages/postgres/component.md
120///
121/// Options inherited from @ref components::ComponentBase :
122/// @include{doc} scripts/docs/en/components_schema/core/src/components/impl/component_base.md
123class Postgres : public ComponentBase {
124public:
125 /// Default shard number
126 static constexpr size_t kDefaultShardNumber = 0;
127 /// Default command control
128 static constexpr storages::postgres::CommandControl kDefaultCommandControl{
129 std::chrono::milliseconds{500}, // network timeout
130 std::chrono::milliseconds{250} // statement timeout
131 };
132
133 /// Component constructor
134 Postgres(const ComponentConfig&, const ComponentContext&);
135 /// Component destructor
136 ~Postgres() override;
137
138 /// Cluster accessor for default shard number
139 storages::postgres::ClusterPtr GetCluster() const;
140
141 /// Cluster accessor for specific shard number
142 storages::postgres::ClusterPtr GetClusterForShard(size_t shard) const;
143
144 /// Get total shard count
145 size_t GetShardCount() const;
146
147 /// Get database object
148 storages::postgres::DatabasePtr GetDatabase() const { return database_; }
149
150 /// Reports statistics for PostgreSQL driver
151 void ExtendStatistics(utils::statistics::Writer& writer);
152
153 static yaml_config::Schema GetStaticConfigSchema();
154
155private:
156 void OnConfigUpdate(const dynamic_config::Snapshot& cfg);
157
158 void OnSecdistUpdate(const storages::secdist::SecdistConfig& secdist);
159
160 std::string name_;
161 std::string db_name_;
162 std::string dbalias_;
163 storages::postgres::ClusterSettings initial_settings_;
164 storages::postgres::DatabasePtr database_;
165
166 // Subscriptions must be the last fields, because the fields above are used
167 // from callbacks.
168 concurrent::AsyncEventSubscriberScope config_subscription_;
169 concurrent::AsyncEventSubscriberScope secdist_subscription_;
170 utils::statistics::Entry statistics_holder_;
171 dynamic_config::Source config_source_;
172};
173
174template <>
175inline constexpr bool kHasValidate<Postgres> = true;
176
177} // namespace components
178
179USERVER_NAMESPACE_END