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