Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions src/include/dbconnector/pool/connection_pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class ConnectionPool : public std::enable_shared_from_this<ConnectionPool<Connec
CACHE_DISABLED,
};

ConnectionPool(uint64_t max_connections = DEFAULT_POOL_SIZE, uint64_t wait_timeout_ms = DEFAULT_POOL_TIMEOUT_MS,
ConnectionPool(uint64_t max_connections = DEFAULT_POOL_SIZE, uint64_t wait_timeout_millis = DEFAULT_POOL_TIMEOUT_MS,
ThreadLocalCacheState tl_cache_state = ThreadLocalCacheState::CACHE_DISABLED);
virtual ~ConnectionPool();

Expand All @@ -39,8 +39,8 @@ class ConnectionPool : public std::enable_shared_from_this<ConnectionPool<Connec

uint64_t GetMaxConnections() const;
void SetMaxConnections(uint64_t new_max);
uint64_t GetWaitTimeoutMs() const;
void SetWaitTimeoutMs(uint64_t timeout_ms);
uint64_t GetWaitTimeoutMillis() const;
void SetWaitTimeoutMillis(uint64_t timeout_millis);

uint64_t GetAvailableConnections() const;
uint64_t GetTotalConnections() const;
Expand All @@ -50,10 +50,10 @@ class ConnectionPool : public std::enable_shared_from_this<ConnectionPool<Connec
uint64_t GetThreadLocalCacheHits() const;
uint64_t GetThreadLocalCacheMisses() const;

uint64_t GetMaxLifetimeSeconds() const;
void SetMaxLifetimeSeconds(uint64_t new_max_lifetime_seconds);
uint64_t GetIdleTimeoutSeconds() const;
void SetIdleTimeoutSeconds(uint64_t new_idle_timeout_seconds);
uint64_t GetMaxLifetimeMillis() const;
void SetMaxLifetimeMillis(uint64_t new_max_lifetime_millis);
uint64_t GetIdleTimeoutMillis() const;
void SetIdleTimeoutMillis(uint64_t new_idle_timeout_millis);

bool EnsureReaperRunning();
void ShutdownReaper();
Expand Down Expand Up @@ -85,7 +85,7 @@ class ConnectionPool : public std::enable_shared_from_this<ConnectionPool<Connec

bool TimeoutEnabled() const;
std::chrono::steady_clock::time_point GetNowForTimeoutPurposes();
static bool TimePointExpired(std::chrono::steady_clock::time_point point, uint64_t timeout,
static bool TimePointExpired(std::chrono::steady_clock::time_point point, uint64_t timeout_millis,
std::chrono::steady_clock::time_point now);
bool IsExpired(const CachedConnection<ConnectionT> &cached_conn, std::chrono::steady_clock::time_point now) const;
bool IsExpired(std::chrono::steady_clock::time_point created_at, std::chrono::steady_clock::time_point now) const;
Expand All @@ -104,7 +104,7 @@ class ConnectionPool : public std::enable_shared_from_this<ConnectionPool<Connec
void DecrementTotalConnections();

std::atomic<uint64_t> max_connections {0};
std::atomic<uint64_t> wait_timeout_ms {0};
std::atomic<uint64_t> wait_timeout_millis {0};

mutable std::mutex pool_lock;
std::condition_variable pool_cv;
Expand All @@ -114,8 +114,8 @@ class ConnectionPool : public std::enable_shared_from_this<ConnectionPool<Connec
std::atomic<uint64_t> total_connections {0};
std::atomic<bool> shutdown_flag {false};

std::atomic<uint64_t> max_lifetime_seconds {0};
std::atomic<uint64_t> idle_timeout_seconds {0};
std::atomic<uint64_t> max_lifetime_millis {0};
std::atomic<uint64_t> idle_timeout_millis {0};

std::thread reaper_thread;
std::condition_variable reaper_cv;
Expand Down
76 changes: 38 additions & 38 deletions src/include/dbconnector/pool/connection_pool_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ namespace dbconnector {
namespace pool {

template <typename ConnectionT>
ConnectionPool<ConnectionT>::ConnectionPool(uint64_t max_connections_p, uint64_t timeout_ms_p,
ConnectionPool<ConnectionT>::ConnectionPool(uint64_t max_connections_p, uint64_t timeout_millis_p,
ThreadLocalCacheState tl_cache_state)
: max_connections(max_connections_p), wait_timeout_ms(timeout_ms_p), total_connections(0), shutdown_flag(false),
tl_cache_enabled(ThreadLocalCacheState::CACHE_ENABLED == tl_cache_state) {
: max_connections(max_connections_p), wait_timeout_millis(timeout_millis_p), total_connections(0),
shutdown_flag(false), tl_cache_enabled(ThreadLocalCacheState::CACHE_ENABLED == tl_cache_state) {
}

template <typename ConnectionT>
Expand Down Expand Up @@ -156,8 +156,8 @@ PooledConnection<ConnectionT> ConnectionPool<ConnectionT>::WaitAcquire() {

std::unique_lock<std::mutex> lock(pool_lock);

auto deadline =
std::chrono::steady_clock::now() + std::chrono::milliseconds(wait_timeout_ms.load(std::memory_order_relaxed));
auto deadline = std::chrono::steady_clock::now() +
std::chrono::milliseconds(wait_timeout_millis.load(std::memory_order_relaxed));

while (true) {
if (shutdown_flag.load(std::memory_order_relaxed)) {
Expand Down Expand Up @@ -203,7 +203,7 @@ PooledConnection<ConnectionT> ConnectionPool<ConnectionT>::WaitAcquire() {
throw PoolException("Connection pool timeout: all " +
std::to_string(max_connections.load(std::memory_order_relaxed)) +
" connections in use, waited " +
std::to_string(wait_timeout_ms.load(std::memory_order_relaxed)) + "ms");
std::to_string(wait_timeout_millis.load(std::memory_order_relaxed)) + "ms");
}
}
}
Expand Down Expand Up @@ -412,14 +412,14 @@ void ConnectionPool<ConnectionT>::SetMaxConnections(uint64_t new_max) {
}

template <typename ConnectionT>
uint64_t ConnectionPool<ConnectionT>::GetWaitTimeoutMs() const {
return wait_timeout_ms.load(std::memory_order_relaxed);
uint64_t ConnectionPool<ConnectionT>::GetWaitTimeoutMillis() const {
return wait_timeout_millis.load(std::memory_order_relaxed);
}

template <typename ConnectionT>
void ConnectionPool<ConnectionT>::SetWaitTimeoutMs(uint64_t timeout_ms) {
void ConnectionPool<ConnectionT>::SetWaitTimeoutMillis(uint64_t timeout_millis) {
std::lock_guard<std::mutex> lock(pool_lock);
wait_timeout_ms.store(timeout_ms, std::memory_order_relaxed);
wait_timeout_millis.store(timeout_millis, std::memory_order_relaxed);
}

template <typename ConnectionT>
Expand All @@ -433,31 +433,31 @@ uint64_t ConnectionPool<ConnectionT>::GetTotalConnections() const {
}

template <typename ConnectionT>
void ConnectionPool<ConnectionT>::SetMaxLifetimeSeconds(uint64_t new_max_lifetime_seconds) {
this->max_lifetime_seconds.store(new_max_lifetime_seconds, std::memory_order_relaxed);
void ConnectionPool<ConnectionT>::SetMaxLifetimeMillis(uint64_t new_max_lifetime_millis) {
this->max_lifetime_millis.store(new_max_lifetime_millis, std::memory_order_relaxed);
reaper_cv.notify_all();
}

template <typename ConnectionT>
uint64_t ConnectionPool<ConnectionT>::GetMaxLifetimeSeconds() const {
return max_lifetime_seconds.load(std::memory_order_relaxed);
uint64_t ConnectionPool<ConnectionT>::GetMaxLifetimeMillis() const {
return max_lifetime_millis.load(std::memory_order_relaxed);
}

template <typename ConnectionT>
void ConnectionPool<ConnectionT>::SetIdleTimeoutSeconds(uint64_t new_idle_timeout_seconds) {
this->idle_timeout_seconds.store(new_idle_timeout_seconds, std::memory_order_relaxed);
void ConnectionPool<ConnectionT>::SetIdleTimeoutMillis(uint64_t new_idle_timeout_millis) {
this->idle_timeout_millis.store(new_idle_timeout_millis, std::memory_order_relaxed);
reaper_cv.notify_all();
}

template <typename ConnectionT>
uint64_t ConnectionPool<ConnectionT>::GetIdleTimeoutSeconds() const {
return idle_timeout_seconds.load(std::memory_order_relaxed);
uint64_t ConnectionPool<ConnectionT>::GetIdleTimeoutMillis() const {
return idle_timeout_millis.load(std::memory_order_relaxed);
}

template <typename ConnectionT>
bool ConnectionPool<ConnectionT>::TimeoutEnabled() const {
return max_lifetime_seconds.load(std::memory_order_relaxed) > 0 ||
idle_timeout_seconds.load(std::memory_order_relaxed) > 0;
return max_lifetime_millis.load(std::memory_order_relaxed) > 0 ||
idle_timeout_millis.load(std::memory_order_relaxed) > 0;
}

template <typename ConnectionT>
Expand All @@ -470,17 +470,17 @@ std::chrono::steady_clock::time_point ConnectionPool<ConnectionT>::GetNowForTime
}

template <typename ConnectionT>
bool ConnectionPool<ConnectionT>::TimePointExpired(std::chrono::steady_clock::time_point point, uint64_t timeout,
bool ConnectionPool<ConnectionT>::TimePointExpired(std::chrono::steady_clock::time_point point, uint64_t timeout_millis,
std::chrono::steady_clock::time_point now) {
if (now.time_since_epoch() == std::chrono::steady_clock::duration::zero()) {
return false;
}
if (timeout == 0) {
if (timeout_millis == 0) {
return false;
}
int64_t age_signed = std::chrono::duration_cast<std::chrono::seconds>(now - point).count();
uint64_t age = age_signed > 0 ? static_cast<uint64_t>(age_signed) : 0;
return age >= timeout;
int64_t age_signed_millis = std::chrono::duration_cast<std::chrono::milliseconds>(now - point).count();
uint64_t age_millis = age_signed_millis > 0 ? static_cast<uint64_t>(age_signed_millis) : 0;
return age_millis >= timeout_millis;
}

template <typename ConnectionT>
Expand All @@ -489,11 +489,11 @@ bool ConnectionPool<ConnectionT>::IsExpired(const CachedConnection<ConnectionT>
if (now.time_since_epoch() == std::chrono::steady_clock::duration::zero()) {
return false;
}
uint64_t max_lifetime_val = max_lifetime_seconds.load(std::memory_order_relaxed);
uint64_t max_lifetime_val = max_lifetime_millis.load(std::memory_order_relaxed);
if (TimePointExpired(cached_conn.GetCreatedAt(), max_lifetime_val, now)) {
return true;
}
uint64_t idle_timeout_val = idle_timeout_seconds.load(std::memory_order_relaxed);
uint64_t idle_timeout_val = idle_timeout_millis.load(std::memory_order_relaxed);
if (TimePointExpired(cached_conn.GetReturnedAt(), idle_timeout_val, now)) {
return true;
}
Expand All @@ -506,7 +506,7 @@ bool ConnectionPool<ConnectionT>::IsExpired(std::chrono::steady_clock::time_poin
if (now.time_since_epoch() == std::chrono::steady_clock::duration::zero()) {
return false;
}
uint64_t max_lifetime_val = max_lifetime_seconds.load(std::memory_order_relaxed);
uint64_t max_lifetime_val = max_lifetime_millis.load(std::memory_order_relaxed);
return TimePointExpired(created_at, max_lifetime_val, now);
}

Expand All @@ -527,15 +527,15 @@ bool ConnectionPool<ConnectionT>::CheckConnectionNotExpiredAndHealthy(std::uniqu
template <typename ConnectionT>
uint64_t ConnectionPool<ConnectionT>::CalcReaperSleepSeconds() {
uint64_t sleep_seconds = 30;
uint64_t max_lifetime_val = max_lifetime_seconds.load(std::memory_order_relaxed);
uint64_t idle_timeout_val = idle_timeout_seconds.load(std::memory_order_relaxed);
uint64_t max_lifetime_seconds = max_lifetime_millis.load(std::memory_order_relaxed) / 1000;
uint64_t idle_timeout_seconds = idle_timeout_millis.load(std::memory_order_relaxed) / 1000;

if (max_lifetime_val > 0 && idle_timeout_val > 0) {
sleep_seconds = (std::min)(max_lifetime_val, idle_timeout_val);
} else if (max_lifetime_val > 0) {
sleep_seconds = max_lifetime_val;
} else if (idle_timeout_val > 0) {
sleep_seconds = idle_timeout_val;
if (max_lifetime_seconds > 0 && idle_timeout_seconds > 0) {
sleep_seconds = (std::min)(max_lifetime_seconds, idle_timeout_seconds);
} else if (max_lifetime_seconds > 0) {
sleep_seconds = max_lifetime_seconds;
} else if (idle_timeout_seconds > 0) {
sleep_seconds = idle_timeout_seconds;
}

sleep_seconds = (std::max<uint64_t>)(1, sleep_seconds / 2);
Expand All @@ -552,8 +552,8 @@ void ConnectionPool<ConnectionT>::ReaperLoop() {
reaper_cv.wait_for(lock, std::chrono::seconds(sleep_seconds),
[this]() { return reaper_shutdown_flag.load(std::memory_order_acquire); });

uint64_t max_lifetime_val = max_lifetime_seconds.load(std::memory_order_relaxed);
uint64_t idle_timeout_val = idle_timeout_seconds.load(std::memory_order_relaxed);
uint64_t max_lifetime_val = max_lifetime_millis.load(std::memory_order_relaxed);
uint64_t idle_timeout_val = idle_timeout_millis.load(std::memory_order_relaxed);

if (max_lifetime_val == 0 && idle_timeout_val == 0) {
reaper_shutdown_flag.store(true, std::memory_order_release);
Expand Down
20 changes: 10 additions & 10 deletions test/test_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,17 @@ TEST_CASE("Test connection pool basic", group_name) {
REQUIRE(pool->ForceAcquire());
pool->SetMaxConnections(42);
REQUIRE(pool->GetMaxConnections() == 42);
pool->SetWaitTimeoutMs(43);
REQUIRE(pool->GetWaitTimeoutMs() == 43);
pool->SetWaitTimeoutMillis(43);
REQUIRE(pool->GetWaitTimeoutMillis() == 43);
REQUIRE(pool->GetAvailableConnections() == 0);
REQUIRE(pool->GetTotalConnections() == 1);
REQUIRE(pool->IsThreadLocalCacheEnabled());
pool->SetThreadLocalCacheEnabled(false);
REQUIRE(!pool->IsThreadLocalCacheEnabled());
pool->SetMaxLifetimeSeconds(44);
REQUIRE(pool->GetMaxLifetimeSeconds() == 44);
pool->SetIdleTimeoutSeconds(45);
REQUIRE(pool->GetIdleTimeoutSeconds() == 45);
pool->SetMaxLifetimeMillis(44);
REQUIRE(pool->GetMaxLifetimeMillis() == 44);
pool->SetIdleTimeoutMillis(45);
REQUIRE(pool->GetIdleTimeoutMillis() == 45);
}

TEST_CASE("Test pool size no thread-local", group_name) {
Expand Down Expand Up @@ -227,7 +227,7 @@ TEST_CASE("Test pool disable running", group_name) {
TEST_CASE("Test pool with a reaper", group_name) {
auto pool = std::make_shared<TestConnectionPool>(4, 1000, false);
REQUIRE(!pool->EnsureReaperRunning());
pool->SetMaxLifetimeSeconds(1);
pool->SetMaxLifetimeMillis(1000);
REQUIRE(pool->EnsureReaperRunning());
REQUIRE(pool->EnsureReaperRunning());

Expand All @@ -244,8 +244,8 @@ TEST_CASE("Test pool with a reaper", group_name) {
std::this_thread::sleep_for(std::chrono::milliseconds(1500));
REQUIRE(0 == pool->GetTotalConnections());

pool->SetIdleTimeoutSeconds(1);
pool->SetMaxLifetimeSeconds(0);
pool->SetIdleTimeoutMillis(1000);
pool->SetMaxLifetimeMillis(0);

{
auto conn = pool->WaitAcquire();
Expand All @@ -264,7 +264,7 @@ TEST_CASE("Test pool with a reaper", group_name) {
TEST_CASE("Test pool with a reaper restart", group_name) {
auto pool = std::make_shared<TestConnectionPool>(4, 1000, false);
REQUIRE(!pool->EnsureReaperRunning());
pool->SetMaxLifetimeSeconds(1);
pool->SetMaxLifetimeMillis(1000);
REQUIRE(pool->EnsureReaperRunning());
pool->ShutdownReaper();

Expand Down
Loading