Skip to content

Commit fb04319

Browse files
KlizzardykevinAlbshansberamongodb
authored
CXX-3100 Check return when acquiring client from pool (#1205)
* Throw exception in `pool::acquire()` on failure to acquire client. * Define new error code: `k_pool_wait_queue_timeout`. * Add a regression test to `src/mongocxx/test/pool.cpp` --------- Co-authored-by: Kevin Albertson <[email protected]> Co-authored-by: hansb <[email protected]> Co-authored-by: Ezra Chung <[email protected]>
1 parent 54693de commit fb04319

File tree

4 files changed

+28
-2
lines changed

4 files changed

+28
-2
lines changed

src/mongocxx/include/mongocxx/v_noabi/mongocxx/exception/error_code.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ enum class error_code : std::int32_t {
108108
// used.
109109
k_invalid_search_index_view,
110110

111+
// Timed out while waiting for a client to be returned to the pool
112+
k_pool_wait_queue_timeout,
113+
111114
// Add new constant string message to error_code.cpp as well!
112115
};
113116

src/mongocxx/lib/mongocxx/v_noabi/mongocxx/exception/error_code.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ class error_category final : public std::error_category {
9292
case error_code::k_invalid_search_index_view:
9393
return "invalid use of default constructed or moved-from "
9494
"mongocxx::search_index_view object";
95+
case error_code::k_pool_wait_queue_timeout:
96+
return "timed out while waiting for a client to be returned to the pool";
9597
default:
9698
return "unknown mongocxx error";
9799
}

src/mongocxx/lib/mongocxx/v_noabi/mongocxx/pool.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,14 @@ pool::entry::operator bool() const noexcept {
131131
pool::entry::entry(pool::entry::unique_client p) : _client(std::move(p)) {}
132132

133133
pool::entry pool::acquire() {
134-
return entry(entry::unique_client(new client(libmongoc::client_pool_pop(_impl->client_pool_t)),
135-
[this](client* client) { _release(client); }));
134+
auto cli = libmongoc::client_pool_pop(_impl->client_pool_t);
135+
if (!cli)
136+
throw exception{
137+
error_code::k_pool_wait_queue_timeout,
138+
"failed to acquire client, possibly due to parameter 'waitQueueTimeoutMS' limits."};
139+
140+
return entry(
141+
entry::unique_client(new client(cli), [this](client* client) { _release(client); }));
136142
}
137143

138144
stdx::optional<pool::entry> pool::try_acquire() {

src/mongocxx/test/pool.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include <bsoncxx/test/catch.hh>
2828
#include <mongocxx/test/catch_helpers.hh>
29+
#include <mongocxx/test/client_helpers.hh>
2930

3031
namespace {
3132
using namespace mongocxx;
@@ -183,4 +184,18 @@ TEST_CASE("a pool is created with an invalid connection string", "[pool]") {
183184

184185
REQUIRE_THROWS_AS(pool{mongocxx::uri(uristr)}, operation_exception);
185186
}
187+
188+
TEST_CASE("acquiring a client throws if waitQueueTimeoutMS expires", "[pool]") {
189+
instance::current();
190+
mongocxx::pool pool{
191+
mongocxx::uri{"mongodb://localhost:27017/?waitQueueTimeoutMS=1&maxPoolSize=1"},
192+
options::pool(test_util::add_test_server_api())};
193+
// Acquire only available client:
194+
auto client = pool.acquire();
195+
CHECK(client);
196+
// Try to acquire again. Expect timeout:
197+
REQUIRE_THROWS_WITH(pool.acquire(),
198+
Catch::Matchers::ContainsSubstring("failed to acquire client"));
199+
}
200+
186201
} // namespace

0 commit comments

Comments
 (0)