userver: userver/storages/redis/dynamic_redis.hpp Source File
Loading...
Searching...
No Matches
dynamic_redis.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/redis/dynamic_redis.hpp
4/// @brief @copybrief storages::redis::DynamicRedis
5
6#include <memory>
7#include <string>
8#include <unordered_map>
9#include <unordered_set>
10
11#include <userver/concurrent/variable.hpp>
12#include <userver/dynamic_config/source.hpp>
13#include <userver/engine/shared_mutex.hpp>
14#include <userver/storages/redis/base.hpp>
15#include <userver/storages/redis/fwd.hpp>
16#include <userver/storages/redis/sharding_strategies.hpp>
17#include <userver/storages/redis/wait_connected_mode.hpp>
18#include <userver/testsuite/redis_control.hpp>
19#include <userver/utils/not_null.hpp>
20#include <userver/utils/statistics/entry.hpp>
21
22USERVER_NAMESPACE_BEGIN
23
24namespace storages::redis {
25
26/// @brief Dynamic configuration settings for Redis clients
27struct DynamicSettings final {
28 struct HostPort {
29 std::string host;
30 int port;
31
32 explicit HostPort(std::string host = {}, int port = 0) noexcept : host(std::move(host)), port(port) {}
33 };
34
35 std::vector<std::string> shards;
36 std::vector<HostPort> sentinels;
37 /// Username for ACL-based auth (Redis 6+). Leave empty for legacy AUTH.
38 std::string username;
39 /// Password for nodes
40 storages::redis::Password password{std::string()};
41 /// Username for sentinel ACL-based auth (Redis 6+). Leave empty for legacy AUTH.
42 std::string sentinel_username;
43 /// Password for sentinels. Available since Redis 5.0.1. For early versions should be always empty.
44 storages::redis::Password sentinel_password{std::string()};
45 storages::redis::ConnectionSecurity secure_connection{storages::redis::ConnectionSecurity::kNone};
46 std::size_t database_index{0};
47 ShardingStrategy sharding_strategy;
48 bool allow_reads_from_master = false;
49};
50
51class ClientImpl;
52
53namespace impl {
54class Sentinel;
55class ThreadPools;
56} // namespace impl
57
58/// @brief Manages dynamically created Redis clients
60public:
61 DynamicRedis() = default;
62
63 void Init(std::shared_ptr<impl::ThreadPools> thread_pools, testsuite::RedisControl testsuite_redis_control);
64
65 ~DynamicRedis();
66
67 /// @brief Adds a new client with the specified name and settings.
68 ///
69 /// @param name the name of the client
70 /// @param settings the dynamic settings for the client
71 /// @return true if the client was added, false if a client with the same name already exists
72 bool AddClient(const std::string& name, const DynamicSettings& settings, dynamic_config::Source& config);
73
74 /// @brief Removes a client with the specified name.
75 ///
76 /// @param name the name of the client to remove
77 /// @return true if the client was removed, false if no client with the specified name exists
78 bool RemoveClient(const std::string& name);
79
80 /// @brief Retrieves a dynamically added client by name.
81 ///
82 /// @param name the name of the client
83 /// @param wait_connected wait mode for the client connection
84 /// @return shared pointer to the client
85 /// throws std::out_of_range exception if there is no client with requested name
87 const std::string& name,
88 storages::redis::RedisWaitConnected wait_connected = {}
89 ) const;
90
91 /// @brief Lists the names of all dynamically added clients.
92 ///
93 /// @return a set of client names
94 std::unordered_set<std::string> ListClients() const;
95
96 /// @brief Writes statistics for all dynamic clients.
97 ///
98 /// @param writer statistics writer
99 void WriteStatistics(utils::statistics::Writer& writer, const MetricsSettings& settings) const;
100
101 void OnConfigUpdate(const dynamic_config::Snapshot& cfg);
102
103private:
104 std::shared_ptr<impl::ThreadPools> thread_pools_;
105 testsuite::RedisControl testsuite_redis_control_;
106
107 concurrent::Variable<std::unordered_map<std::string, std::shared_ptr<ClientImpl>>, engine::SharedMutex>
108 dynamic_clients_;
109};
110
111} // namespace storages::redis
112
113USERVER_NAMESPACE_END