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 /// Password for nodes
38 storages::redis::Password password{std::string()};
39 /// Password for sentinels. Available since Redis 5.0.1. For early versions should be always empty.
40 storages::redis::Password sentinel_password{std::string()};
41 storages::redis::ConnectionSecurity secure_connection{storages::redis::ConnectionSecurity::kNone};
42 std::size_t database_index{0};
43 ShardingStrategy sharding_strategy;
44 bool allow_reads_from_master = false;
45};
46
47class ClientImpl;
48
49namespace impl {
50class Sentinel;
51class ThreadPools;
52} // namespace impl
53
54/// @brief Manages dynamically created Redis clients
56public:
57 DynamicRedis() = default;
58
59 void Init(std::shared_ptr<impl::ThreadPools> thread_pools, testsuite::RedisControl testsuite_redis_control);
60
61 ~DynamicRedis();
62
63 /// @brief Adds a new client with the specified name and settings.
64 ///
65 /// @param name the name of the client
66 /// @param settings the dynamic settings for the client
67 /// @return true if the client was added, false if a client with the same name already exists
68 bool AddClient(const std::string& name, const DynamicSettings& settings, dynamic_config::Source& config);
69
70 /// @brief Removes a client with the specified name.
71 ///
72 /// @param name the name of the client to remove
73 /// @return true if the client was removed, false if no client with the specified name exists
74 bool RemoveClient(const std::string& name);
75
76 /// @brief Retrieves a dynamically added client by name.
77 ///
78 /// @param name the name of the client
79 /// @param wait_connected wait mode for the client connection
80 /// @return shared pointer to the client
81 /// throws std::out_of_range exception if there is no client with requested name
83 const std::string& name,
84 storages::redis::RedisWaitConnected wait_connected = {}
85 ) const;
86
87 /// @brief Lists the names of all dynamically added clients.
88 ///
89 /// @return a set of client names
90 std::unordered_set<std::string> ListClients() const;
91
92 /// @brief Writes statistics for all dynamic clients.
93 ///
94 /// @param writer statistics writer
95 void WriteStatistics(utils::statistics::Writer& writer, const MetricsSettings& settings) const;
96
97 void OnConfigUpdate(const dynamic_config::Snapshot& cfg);
98
99private:
100 std::shared_ptr<impl::ThreadPools> thread_pools_;
101 testsuite::RedisControl testsuite_redis_control_;
102
103 concurrent::Variable<std::unordered_map<std::string, std::shared_ptr<ClientImpl>>, engine::SharedMutex>
104 dynamic_clients_;
105};
106
107} // namespace storages::redis
108
109USERVER_NAMESPACE_END