Github   Telegram
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#include <vector>
8
9#include <userver/components/loggable_component_base.hpp>
10#include <userver/concurrent/async_event_source.hpp>
11#include <userver/dynamic_config/snapshot.hpp>
12#include <userver/engine/mutex.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// clang-format off
22
23/// @ingroup userver_components
24///
25/// @brief PosgreSQL client component
26///
27/// Provides access to a PostgreSQL cluster.
28///
29/// ## Dynamic options:
30/// * @ref POSTGRES_DEFAULT_COMMAND_CONTROL
31/// * @ref POSTGRES_HANDLERS_COMMAND_CONTROL
32/// * @ref POSTGRES_QUERIES_COMMAND_CONTROL
33/// * @ref POSTGRES_CONNECTION_POOL_SETTINGS
34/// * @ref POSTGRES_CONNECTION_SETTINGS
35/// * @ref POSTGRES_CONNECTION_PIPELINE_ENABLED
36/// * @ref POSTGRES_STATEMENT_METRICS_SETTINGS
37///
38/// ## Static configuration example:
39///
40/// ```
41/// # yaml
42/// postgres-taxi:
43/// dbalias: taxi
44/// blocking_task_processor: task-processor-name
45/// max_replication_lag: 60s
46/// min_pool_size: 4
47/// max_pool_size: 15
48/// max_queue_size: 200
49/// max_statement_metrics: 50
50/// ```
51/// You must specify either `dbalias` or `conn_info`.
52/// If the component is configured with an alias, it will lookup connection data
53/// in secdist.json
54///
55/// You must specify `blocking_task_processor` as well.
56///
57/// `max_replication_lag` can be used to tune replication lag limit for replicas.
58/// Once the replica lag exceeds this value it will be automatically disabled.
59/// Note, however, that client-size lag detection is not precise in nature
60/// and can only provide the precision of couple seconds.
61///
62/// ## Secdist format
63///
64/// A PosgreSQL alias in secdist is described as a JSON array of objects
65/// containing a single cluster description. There are two formats of describing
66/// a cluster, the first one assigns predefined roles to DSNs, the second one
67/// is just a list of DSNs and the Postgres component takes care of discovering
68/// the cluster's topology itself.
69///
70/// ### Predefined roles
71///
72/// In predefined roles format the component requires single-host connection
73/// strings.
74///
75/// ```json
76/// {
77/// "shard_number" : 0,
78/// "master": "host=localhost dbname=example",
79/// "sync_slave": "host=localhost dbname=example",
80/// "slaves": [
81/// "host=localhost dbname=example"
82/// ]
83/// }
84/// ```
85///
86/// The predefined roles format is deprecated and the support will be removed
87/// soon.
88///
89/// ### Automatic discovery
90///
91/// In automatic discovery format the connection strings are any valid
92/// PostgreSQL connection strings including multi-host ones with the exception
93/// of `target_session_attrs` which will be ignored.
94///
95/// ```json
96/// {
97/// "shard_number" : 0,
98/// "hosts": [
99/// "host=host1,host2,host3 dbname=example",
100/// "postgresql://host1:5432,host2:6432,host3:12000/example"
101/// ]
102/// }
103/// ```
104///
105/// The `shard_number` parameter is required in both formats and must match the
106/// index of cluster description object in the alias array.
107///
108/// Please see [PostgreSQL documentation](https://www.postgresql.org/docs/12/libpq-connect.html#LIBPQ-CONNSTRING)
109/// on connection strings.
110///
111/// ## Static options:
112/// Name | Description | Default value
113/// ----------------------- | --------------------------------------------------------- | -------------
114/// dbalias | name of the database in secdist config (if available) | --
115/// dbconnection | connection DSN string (used if no dbalias specified) | --
116/// blocking_task_processor | name of task processor for background blocking operations | --
117/// max_replication_lag | replication lag limit for usable slaves | 60s
118/// min_pool_size | number of connections created initially | 4
119/// max_pool_size | limit of connections count | 15
120/// sync-start | perform initial connections synchronously | false
121/// dns_resolver | server hostname resolver type (getaddrinfo or async) | 'getaddrinfo'
122/// persistent-prepared-statements | cache prepared statements or not | true
123/// user-types-enabled | disabling will disallow use of user-defined types | true
124/// ignore_unused_query_params| disable check for not-NULL query params that are not used in query| false
125/// monitoring-dbalias | name of the database for monitorings | calculated from dbalias or dbconnection options
126/// max_prepared_cache_size | prepared statements cache size limit | 5000
127/// max_statement_metrics | limit of exported metrics for named statements | 0
128/// min_pool_size | number of connections created initially | 4
129/// max_pool_size | maximum number of created connections | 15
130/// max_queue_size | maximum number of clients waiting for a connection | 200
131/// connecting_limit | limit for concurrent establishing connections number per pool (0 - unlimited) | 0
132
133// clang-format on
134
136 public:
137 static constexpr auto kDefaultMaxReplicationLag = std::chrono::seconds{60};
138 /// Default shard number
139 static constexpr size_t kDefaultShardNumber = 0;
140 /// Default command control
141 static constexpr storages::postgres::CommandControl kDefaultCommandControl{
142 std::chrono::milliseconds{500}, // network timeout
143 std::chrono::milliseconds{250} // statement timeout
144 };
145
146 /// Component constructor
147 Postgres(const ComponentConfig&, const ComponentContext&);
148 /// Component destructor
149 ~Postgres() override;
150
151 /// Cluster accessor for default shard number
152 storages::postgres::ClusterPtr GetCluster() const;
153
154 /// Cluster accessor for specific shard number
155 storages::postgres::ClusterPtr GetClusterForShard(size_t shard) const;
156
157 /// Get total shard count
159
160 /// Get database object
161 storages::postgres::DatabasePtr GetDatabase() const { return database_; }
162
163 /// Reports statistics for PostgreSQL driver
164 formats::json::Value ExtendStatistics(
165 const utils::statistics::StatisticsRequest& /*request*/);
166
167 static yaml_config::Schema GetStaticConfigSchema();
168
169 private:
170 void OnConfigUpdate(const dynamic_config::Snapshot& cfg);
171
172 concurrent::AsyncEventSubscriberScope config_subscription_;
173
174 utils::statistics::Entry statistics_holder_;
175
176 std::string name_;
177 std::string db_name_;
178 storages::postgres::DatabasePtr database_;
179};
180
181template <>
182inline constexpr bool kHasValidate<Postgres> = true;
183
184} // namespace components
185
186USERVER_NAMESPACE_END