diff --git a/src/include/dbconnector/pool/connection_pool.hpp b/src/include/dbconnector/pool/connection_pool.hpp index 1fabc17..b8f9214 100644 --- a/src/include/dbconnector/pool/connection_pool.hpp +++ b/src/include/dbconnector/pool/connection_pool.hpp @@ -26,7 +26,7 @@ class ConnectionPool : public std::enable_shared_from_this &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; @@ -104,7 +104,7 @@ class ConnectionPool : public std::enable_shared_from_this max_connections {0}; - std::atomic wait_timeout_ms {0}; + std::atomic wait_timeout_millis {0}; mutable std::mutex pool_lock; std::condition_variable pool_cv; @@ -114,8 +114,8 @@ class ConnectionPool : public std::enable_shared_from_this total_connections {0}; std::atomic shutdown_flag {false}; - std::atomic max_lifetime_seconds {0}; - std::atomic idle_timeout_seconds {0}; + std::atomic max_lifetime_millis {0}; + std::atomic idle_timeout_millis {0}; std::thread reaper_thread; std::condition_variable reaper_cv; diff --git a/src/include/dbconnector/pool/connection_pool_impl.hpp b/src/include/dbconnector/pool/connection_pool_impl.hpp index 0ecd1a7..ae31a81 100644 --- a/src/include/dbconnector/pool/connection_pool_impl.hpp +++ b/src/include/dbconnector/pool/connection_pool_impl.hpp @@ -13,10 +13,10 @@ namespace dbconnector { namespace pool { template -ConnectionPool::ConnectionPool(uint64_t max_connections_p, uint64_t timeout_ms_p, +ConnectionPool::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 @@ -156,8 +156,8 @@ PooledConnection ConnectionPool::WaitAcquire() { std::unique_lock 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)) { @@ -203,7 +203,7 @@ PooledConnection ConnectionPool::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"); } } } @@ -412,14 +412,14 @@ void ConnectionPool::SetMaxConnections(uint64_t new_max) { } template -uint64_t ConnectionPool::GetWaitTimeoutMs() const { - return wait_timeout_ms.load(std::memory_order_relaxed); +uint64_t ConnectionPool::GetWaitTimeoutMillis() const { + return wait_timeout_millis.load(std::memory_order_relaxed); } template -void ConnectionPool::SetWaitTimeoutMs(uint64_t timeout_ms) { +void ConnectionPool::SetWaitTimeoutMillis(uint64_t timeout_millis) { std::lock_guard lock(pool_lock); - wait_timeout_ms.store(timeout_ms, std::memory_order_relaxed); + wait_timeout_millis.store(timeout_millis, std::memory_order_relaxed); } template @@ -433,31 +433,31 @@ uint64_t ConnectionPool::GetTotalConnections() const { } template -void ConnectionPool::SetMaxLifetimeSeconds(uint64_t new_max_lifetime_seconds) { - this->max_lifetime_seconds.store(new_max_lifetime_seconds, std::memory_order_relaxed); +void ConnectionPool::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 -uint64_t ConnectionPool::GetMaxLifetimeSeconds() const { - return max_lifetime_seconds.load(std::memory_order_relaxed); +uint64_t ConnectionPool::GetMaxLifetimeMillis() const { + return max_lifetime_millis.load(std::memory_order_relaxed); } template -void ConnectionPool::SetIdleTimeoutSeconds(uint64_t new_idle_timeout_seconds) { - this->idle_timeout_seconds.store(new_idle_timeout_seconds, std::memory_order_relaxed); +void ConnectionPool::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 -uint64_t ConnectionPool::GetIdleTimeoutSeconds() const { - return idle_timeout_seconds.load(std::memory_order_relaxed); +uint64_t ConnectionPool::GetIdleTimeoutMillis() const { + return idle_timeout_millis.load(std::memory_order_relaxed); } template bool ConnectionPool::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 @@ -470,17 +470,17 @@ std::chrono::steady_clock::time_point ConnectionPool::GetNowForTime } template -bool ConnectionPool::TimePointExpired(std::chrono::steady_clock::time_point point, uint64_t timeout, +bool ConnectionPool::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(now - point).count(); - uint64_t age = age_signed > 0 ? static_cast(age_signed) : 0; - return age >= timeout; + int64_t age_signed_millis = std::chrono::duration_cast(now - point).count(); + uint64_t age_millis = age_signed_millis > 0 ? static_cast(age_signed_millis) : 0; + return age_millis >= timeout_millis; } template @@ -489,11 +489,11 @@ bool ConnectionPool::IsExpired(const CachedConnection 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; } @@ -506,7 +506,7 @@ bool ConnectionPool::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); } @@ -527,15 +527,15 @@ bool ConnectionPool::CheckConnectionNotExpiredAndHealthy(std::uniqu template uint64_t ConnectionPool::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)(1, sleep_seconds / 2); @@ -552,8 +552,8 @@ void ConnectionPool::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); diff --git a/test/test_pool.cpp b/test/test_pool.cpp index cbab949..7d2d6fa 100644 --- a/test/test_pool.cpp +++ b/test/test_pool.cpp @@ -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) { @@ -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(4, 1000, false); REQUIRE(!pool->EnsureReaperRunning()); - pool->SetMaxLifetimeSeconds(1); + pool->SetMaxLifetimeMillis(1000); REQUIRE(pool->EnsureReaperRunning()); REQUIRE(pool->EnsureReaperRunning()); @@ -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(); @@ -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(4, 1000, false); REQUIRE(!pool->EnsureReaperRunning()); - pool->SetMaxLifetimeSeconds(1); + pool->SetMaxLifetimeMillis(1000); REQUIRE(pool->EnsureReaperRunning()); pool->ShutdownReaper();