Skip to content

Commit 0975d56

Browse files
Olex1313apolukhin
authored andcommitted
feat odbc: add connection pool to odbc
Tests: протестировано CI Pull Request resolved: #938 commit_hash:38ba6176628f3ed9b23b01a875ed2ce93ce44999
1 parent cd77cbd commit 0975d56

14 files changed

Lines changed: 356 additions & 23 deletions

File tree

.mapping.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2769,13 +2769,18 @@
27692769
"odbc/include/userver/storages/odbc/query.hpp":"taxi/uservices/userver/odbc/include/userver/storages/odbc/query.hpp",
27702770
"odbc/include/userver/storages/odbc/result_set.hpp":"taxi/uservices/userver/odbc/include/userver/storages/odbc/result_set.hpp",
27712771
"odbc/include/userver/storages/odbc/row.hpp":"taxi/uservices/userver/odbc/include/userver/storages/odbc/row.hpp",
2772+
"odbc/include/userver/storages/odbc/settings.hpp":"taxi/uservices/userver/odbc/include/userver/storages/odbc/settings.hpp",
27722773
"odbc/library.yaml":"taxi/uservices/userver/odbc/library.yaml",
27732774
"odbc/src/storages/odbc/cluster.cpp":"taxi/uservices/userver/odbc/src/storages/odbc/cluster.cpp",
27742775
"odbc/src/storages/odbc/cluster_types.cpp":"taxi/uservices/userver/odbc/src/storages/odbc/cluster_types.cpp",
27752776
"odbc/src/storages/odbc/detail/cluster_impl.cpp":"taxi/uservices/userver/odbc/src/storages/odbc/detail/cluster_impl.cpp",
27762777
"odbc/src/storages/odbc/detail/cluster_impl.hpp":"taxi/uservices/userver/odbc/src/storages/odbc/detail/cluster_impl.hpp",
2778+
"odbc/src/storages/odbc/detail/conn_ptr.cpp":"taxi/uservices/userver/odbc/src/storages/odbc/detail/conn_ptr.cpp",
2779+
"odbc/src/storages/odbc/detail/conn_ptr.hpp":"taxi/uservices/userver/odbc/src/storages/odbc/detail/conn_ptr.hpp",
27772780
"odbc/src/storages/odbc/detail/connection.cpp":"taxi/uservices/userver/odbc/src/storages/odbc/detail/connection.cpp",
27782781
"odbc/src/storages/odbc/detail/connection.hpp":"taxi/uservices/userver/odbc/src/storages/odbc/detail/connection.hpp",
2782+
"odbc/src/storages/odbc/detail/pool.cpp":"taxi/uservices/userver/odbc/src/storages/odbc/detail/pool.cpp",
2783+
"odbc/src/storages/odbc/detail/pool.hpp":"taxi/uservices/userver/odbc/src/storages/odbc/detail/pool.hpp",
27792784
"odbc/src/storages/odbc/detail/result_wrapper.cpp":"taxi/uservices/userver/odbc/src/storages/odbc/detail/result_wrapper.cpp",
27802785
"odbc/src/storages/odbc/detail/result_wrapper.hpp":"taxi/uservices/userver/odbc/src/storages/odbc/detail/result_wrapper.hpp",
27812786
"odbc/src/storages/odbc/exception.cpp":"taxi/uservices/userver/odbc/src/storages/odbc/exception.cpp",

odbc/include/userver/storages/odbc/cluster.hpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,12 @@
33
#include <userver/storages/odbc/cluster_types.hpp>
44
#include <userver/storages/odbc/query.hpp>
55
#include <userver/storages/odbc/result_set.hpp>
6+
#include <userver/storages/odbc/settings.hpp>
67

78
USERVER_NAMESPACE_BEGIN
89

910
namespace storages::odbc {
1011

11-
namespace settings {
12-
struct ODBCClusterSettings {
13-
/// @param dsns list of DSNs to connect to, first DSN is used as a master
14-
std::vector<std::string> dsns;
15-
};
16-
} // namespace settings
17-
1812
namespace detail {
1913

2014
class ClusterImpl;

odbc/include/userver/storages/odbc/odbc_fwd.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ using ClusterPtr = std::shared_ptr<Cluster>;
2020
namespace detail {
2121
class ResultWrapper;
2222
using ResultWrapperPtr = std::shared_ptr<const ResultWrapper>;
23+
24+
class ConnectionPtr;
25+
26+
class Pool;
27+
using PoolPtr = std::shared_ptr<Pool>;
2328
} // namespace detail
2429

2530
} // namespace storages::odbc
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <vector>
5+
6+
USERVER_NAMESPACE_BEGIN
7+
8+
namespace storages::odbc::settings {
9+
10+
struct PoolSettings final {
11+
std::size_t minSize{5};
12+
std::size_t maxSize{10};
13+
};
14+
15+
struct HostSettings final {
16+
const std::string dsn;
17+
PoolSettings pool;
18+
};
19+
20+
struct ODBCClusterSettings final {
21+
std::vector<HostSettings> pools;
22+
};
23+
24+
} // namespace storages::odbc::settings
25+
26+
USERVER_NAMESPACE_END

odbc/src/storages/odbc/cluster.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ USERVER_NAMESPACE_BEGIN
99
namespace storages::odbc {
1010

1111
Cluster::Cluster(const settings::ODBCClusterSettings& settings)
12-
: impl_(std::make_unique<detail::ClusterImpl>(settings.dsns)) {
13-
UASSERT(settings.dsns.size() > 0);
12+
: impl_(std::make_unique<detail::ClusterImpl>(settings)) {
13+
UASSERT(settings.pools.size() > 0);
1414
}
1515

1616
Cluster::~Cluster() = default;

odbc/src/storages/odbc/detail/cluster_impl.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <storages/odbc/detail/cluster_impl.hpp>
22

3-
#include <storages/odbc/detail/connection.hpp>
3+
#include <storages/odbc/detail/pool.hpp>
44
#include <userver/storages/odbc/cluster_types.hpp>
55

66
#include <userver/utils/assert.hpp>
@@ -9,19 +9,21 @@ USERVER_NAMESPACE_BEGIN
99

1010
namespace storages::odbc::detail {
1111

12-
ClusterImpl::ClusterImpl(const std::vector<std::string>& dsns) : dsns_(dsns) {
13-
for (const auto& dsn : dsns) {
14-
connections_.push_back(std::make_unique<Connection>(dsn));
12+
ClusterImpl::ClusterImpl(const settings::ODBCClusterSettings& settings) {
13+
for (const auto& host : settings.pools) {
14+
pools_.push_back(std::make_shared<Pool>(host.dsn, host.pool.minSize, host.pool.maxSize));
1515
}
1616
}
1717

1818
ResultSet ClusterImpl::Execute([[maybe_unused]] ClusterHostTypeFlags flags, const Query& query) {
19-
if (flags & ClusterHostType::kMaster || flags & ClusterHostType::kNone || connections_.size() == 1) {
20-
return connections_[0]->Query(query.Statement());
19+
if (flags & ClusterHostType::kMaster || flags & ClusterHostType::kNone || pools_.size() == 1) {
20+
auto conn = pools_[0]->Acquire();
21+
return conn->Query(query.Statement());
2122
}
2223

23-
UINVARIANT(connections_.size() > 1, "Cluster should have at least 2 connections for ClusterHostType::kSlave");
24-
return connections_[1]->Query(query.Statement());
24+
UINVARIANT(pools_.size() > 1, "Cluster should have at least 2 connections for ClusterHostType::kSlave");
25+
auto conn = pools_[1]->Acquire();
26+
return conn->Query(query.Statement());
2527
}
2628

2729
} // namespace storages::odbc::detail

odbc/src/storages/odbc/detail/cluster_impl.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,25 @@
77
#include <userver/storages/odbc/cluster_types.hpp>
88
#include <userver/storages/odbc/query.hpp>
99
#include <userver/storages/odbc/result_set.hpp>
10+
#include <userver/storages/odbc/settings.hpp>
1011

11-
#include <storages/odbc/detail/connection.hpp>
12+
#include <storages/odbc/detail/pool.hpp>
1213

1314
USERVER_NAMESPACE_BEGIN
1415

1516
namespace storages::odbc::detail {
1617

1718
class ClusterImpl {
1819
public:
19-
ClusterImpl(const std::vector<std::string>& dsns);
20+
ClusterImpl(const settings::ODBCClusterSettings& settings);
2021

2122
~ClusterImpl() = default;
2223

2324
ResultSet Execute(ClusterHostTypeFlags flags, const Query& query);
2425

2526
private:
2627
std::vector<std::string> dsns_;
27-
std::vector<std::unique_ptr<Connection>> connections_;
28+
std::vector<std::shared_ptr<Pool>> pools_;
2829
};
2930
} // namespace storages::odbc::detail
3031

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include <storages/odbc/detail/conn_ptr.hpp>
2+
3+
#include <userver/utils/assert.hpp>
4+
5+
#include <storages/odbc/detail/pool.hpp>
6+
7+
USERVER_NAMESPACE_BEGIN
8+
9+
namespace storages::odbc::detail {
10+
11+
ConnectionPtr::ConnectionPtr(std::shared_ptr<Pool>&& pool, std::unique_ptr<Connection>&& connection)
12+
: pool_{std::move(pool)}, conn_{std::move(connection)} {}
13+
14+
ConnectionPtr::~ConnectionPtr() { Reset(nullptr, nullptr); }
15+
16+
ConnectionPtr::ConnectionPtr(ConnectionPtr&& other) noexcept { Reset(std::move(other.conn_), std::move(other.pool_)); }
17+
18+
ConnectionPtr& ConnectionPtr::operator=(ConnectionPtr&& other) noexcept {
19+
Reset(std::move(other.conn_), std::move(other.pool_));
20+
return *this;
21+
}
22+
23+
bool ConnectionPtr::IsValid() const noexcept { return conn_ != nullptr; }
24+
25+
Connection* ConnectionPtr::get() const noexcept { return conn_.get(); }
26+
27+
Connection& ConnectionPtr::operator*() const {
28+
UASSERT_MSG(conn_, "Dereferencing null connection pointer");
29+
return *conn_;
30+
}
31+
32+
Connection* ConnectionPtr::operator->() const noexcept { return conn_.get(); }
33+
34+
void ConnectionPtr::Reset(std::unique_ptr<Connection> conn, std::shared_ptr<Pool> pool) {
35+
Release();
36+
conn_ = std::move(conn);
37+
pool_ = std::move(pool);
38+
}
39+
40+
void ConnectionPtr::Release() {
41+
if (!pool_) return;
42+
43+
if (conn_) {
44+
pool_->Release(std::move(conn_));
45+
}
46+
}
47+
48+
} // namespace storages::odbc::detail
49+
50+
USERVER_NAMESPACE_END
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#pragma once
2+
3+
#include <memory>
4+
5+
#include <storages/odbc/detail/connection.hpp>
6+
#include <userver/storages/odbc/odbc_fwd.hpp>
7+
8+
USERVER_NAMESPACE_BEGIN
9+
10+
namespace storages::odbc::detail {
11+
12+
class ConnectionPtr {
13+
public:
14+
ConnectionPtr(std::shared_ptr<Pool>&& pool, std::unique_ptr<Connection>&& connection);
15+
16+
~ConnectionPtr();
17+
18+
ConnectionPtr(ConnectionPtr&& other) noexcept;
19+
ConnectionPtr& operator=(ConnectionPtr&& other) noexcept;
20+
21+
bool IsValid() const noexcept;
22+
Connection* get() const noexcept;
23+
24+
Connection& operator*() const;
25+
Connection* operator->() const noexcept;
26+
27+
private:
28+
void Reset(std::unique_ptr<Connection> conn, std::shared_ptr<Pool> pool);
29+
void Release();
30+
31+
std::shared_ptr<Pool> pool_;
32+
std::unique_ptr<Connection> conn_;
33+
};
34+
35+
} // namespace storages::odbc::detail
36+
37+
USERVER_NAMESPACE_END

odbc/src/storages/odbc/detail/connection.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,18 @@ ResultSet Connection::Query(const std::string& query) {
118118
return ResultSet(std::move(wrapper));
119119
}
120120

121+
bool Connection::IsBroken() const {
122+
SQLUINTEGER state = 0;
123+
SQLRETURN ret = SQLGetConnectAttr(handle_.get(), SQL_ATTR_CONNECTION_DEAD, &state, sizeof(state), nullptr);
124+
if (!SQL_SUCCEEDED(ret) || state == SQL_CD_TRUE) {
125+
return true;
126+
}
127+
128+
return false;
129+
}
130+
131+
void Connection::NotifyBroken() {}
132+
121133
} // namespace storages::odbc
122134

123135
USERVER_NAMESPACE_END

0 commit comments

Comments
 (0)