1#pragma once
2
3#include "Pool.h"
4
5
6#define MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_START_CONNECTIONS 1
7#define MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_CONNECTIONS 16
8#define MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_TRIES 3
9
10
11namespace mysqlxx
12{
13 /** MySQL connection pool with support of failover.
14 * Have information about replicas and their priorities.
15 * Tries to connect to replica in an order of priority. When equal priority, choose replica with maximum time without connections.
16 *
17 * It could be configured without replicas, exactly as ordinary Pool:
18 *
19 * <mysql_metrica>
20 * <host>mtstat01c*</host>
21 * <port>3306</port>
22 * <user>metrica</user>
23 * <password></password>
24 * <db>Metrica</db>
25 * </mysql_metrica>
26 *
27 * Or like this:
28 *
29 * <mysql_metrica>
30 * <replica>
31 * <host>mtstat01c</host>
32 * <port>3306</port>
33 * <user>metrica</user>
34 * <password></password>
35 * <db>Metrica</db>
36 * <priority>0</priority>
37 * </replica>
38 * <replica>
39 * <host>mtstat01d</host>
40 * <port>3306</port>
41 * <user>metrica</user>
42 * <password></password>
43 * <db>Metrica</db>
44 * <priority>1</priority>
45 * </replica>
46 * </mysql_metrica>
47 *
48 * Or like this:
49 *
50 * <mysql_metrica>
51 * <port>3306</port>
52 * <user>metrica</user>
53 * <password></password>
54 * <db>Metrica</db>
55 * <replica>
56 * <host>mtstat01c</host>
57 * <priority>0</priority>
58 * </replica>
59 * <replica>
60 * <host>mtstat01d</host>
61 * <priority>1</priority>
62 * </replica>
63 * </mysql_metrica>
64 */
65 class PoolWithFailover final
66 {
67 private:
68 using PoolPtr = std::shared_ptr<Pool>;
69 using Replicas = std::vector<PoolPtr>;
70
71 /// [priority][index] -> replica.
72 using ReplicasByPriority = std::map<int, Replicas>;
73
74 ReplicasByPriority replicas_by_priority;
75
76 /// Number of connection tries.
77 size_t max_tries;
78 /// Mutex for set of replicas.
79 std::mutex mutex;
80
81 public:
82 using Entry = Pool::Entry;
83
84 /**
85 * config_name Name of parameter in configuration file.
86 * default_connections Number of connection in pool to each replica at start.
87 * max_connections Maximum number of connections in pool to each replica.
88 * max_tries_ Max number of connection tries.
89 */
90 PoolWithFailover(const std::string & config_name,
91 unsigned default_connections = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_START_CONNECTIONS,
92 unsigned max_connections = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_CONNECTIONS,
93 size_t max_tries = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_TRIES);
94
95 PoolWithFailover(const Poco::Util::AbstractConfiguration & config,
96 const std::string & config_name,
97 unsigned default_connections = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_START_CONNECTIONS,
98 unsigned max_connections = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_CONNECTIONS,
99 size_t max_tries = MYSQLXX_POOL_WITH_FAILOVER_DEFAULT_MAX_TRIES);
100
101 PoolWithFailover(const PoolWithFailover & other);
102
103 PoolWithFailover & operator=(const PoolWithFailover &) = delete;
104
105 /** Allocates a connection to use. */
106 Entry Get();
107 };
108}
109