# HG changeset patch # User Sebastien Jodogne # Date 1733926928 -3600 # Node ID c17022c1fa29a927390ce73a7237363addc10e45 # Parent 2fd6be965fcc1889dba620ffa7f8d2b18460e700 added a housekeeping thread diff -r 2fd6be965fcc -r c17022c1fa29 Framework/Plugins/DatabaseBackendAdapterV3.cpp --- a/Framework/Plugins/DatabaseBackendAdapterV3.cpp Wed Dec 04 17:08:41 2024 +0100 +++ b/Framework/Plugins/DatabaseBackendAdapterV3.cpp Wed Dec 11 15:22:08 2024 +0100 @@ -1814,7 +1814,8 @@ void DatabaseBackendAdapterV3::Register(IndexBackend* backend, size_t countConnections, - unsigned int maxDatabaseRetries) + unsigned int maxDatabaseRetries, + unsigned int housekeepingDelaySeconds) { std::unique_ptr protection(backend); @@ -1905,7 +1906,7 @@ if (OrthancPluginRegisterDatabaseBackendV3( context, ¶ms, sizeof(params), maxDatabaseRetries, - new IndexConnectionsPool(protection.release(), countConnections)) != OrthancPluginErrorCode_Success) + new IndexConnectionsPool(protection.release(), countConnections, housekeepingDelaySeconds)) != OrthancPluginErrorCode_Success) { delete backend; throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "Unable to register the database backend"); diff -r 2fd6be965fcc -r c17022c1fa29 Framework/Plugins/DatabaseBackendAdapterV3.h --- a/Framework/Plugins/DatabaseBackendAdapterV3.h Wed Dec 04 17:08:41 2024 +0100 +++ b/Framework/Plugins/DatabaseBackendAdapterV3.h Wed Dec 11 15:22:08 2024 +0100 @@ -60,7 +60,8 @@ static void Register(IndexBackend* backend, size_t countConnections, - unsigned int maxDatabaseRetries); + unsigned int maxDatabaseRetries, + unsigned int housekeepingDelaySeconds); static void Finalize(); }; diff -r 2fd6be965fcc -r c17022c1fa29 Framework/Plugins/DatabaseBackendAdapterV4.cpp --- a/Framework/Plugins/DatabaseBackendAdapterV4.cpp Wed Dec 04 17:08:41 2024 +0100 +++ b/Framework/Plugins/DatabaseBackendAdapterV4.cpp Wed Dec 11 15:22:08 2024 +0100 @@ -1465,9 +1465,10 @@ void DatabaseBackendAdapterV4::Register(IndexBackend* backend, size_t countConnections, - unsigned int maxDatabaseRetries) + unsigned int maxDatabaseRetries, + unsigned int housekeepingDelaySeconds) { - std::unique_ptr pool(new IndexConnectionsPool(backend, countConnections)); + std::unique_ptr pool(new IndexConnectionsPool(backend, countConnections, housekeepingDelaySeconds)); if (isBackendInUse_) { diff -r 2fd6be965fcc -r c17022c1fa29 Framework/Plugins/DatabaseBackendAdapterV4.h --- a/Framework/Plugins/DatabaseBackendAdapterV4.h Wed Dec 04 17:08:41 2024 +0100 +++ b/Framework/Plugins/DatabaseBackendAdapterV4.h Wed Dec 11 15:22:08 2024 +0100 @@ -50,7 +50,8 @@ public: static void Register(IndexBackend* backend, size_t countConnections, - unsigned int maxDatabaseRetries); + unsigned int maxDatabaseRetries, + unsigned int housekeepingDelaySeconds); static void Finalize(); }; diff -r 2fd6be965fcc -r c17022c1fa29 Framework/Plugins/IndexBackend.cpp --- a/Framework/Plugins/IndexBackend.cpp Wed Dec 04 17:08:41 2024 +0100 +++ b/Framework/Plugins/IndexBackend.cpp Wed Dec 11 15:22:08 2024 +0100 @@ -2982,7 +2982,8 @@ void IndexBackend::Register(IndexBackend* backend, size_t countConnections, - unsigned int maxDatabaseRetries) + unsigned int maxDatabaseRetries, + unsigned int housekeepingDelaySeconds) { if (backend == NULL) { @@ -2996,7 +2997,7 @@ # if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 0) if (OrthancPluginCheckVersionAdvanced(backend->GetContext(), 1, 12, 0) == 1) { - DatabaseBackendAdapterV4::Register(backend, countConnections, maxDatabaseRetries); + DatabaseBackendAdapterV4::Register(backend, countConnections, maxDatabaseRetries, housekeepingDelaySeconds); return; } # endif @@ -3006,7 +3007,7 @@ # if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 9, 2) if (OrthancPluginCheckVersionAdvanced(backend->GetContext(), 1, 9, 2) == 1) { - DatabaseBackendAdapterV3::Register(backend, countConnections, maxDatabaseRetries); + DatabaseBackendAdapterV3::Register(backend, countConnections, maxDatabaseRetries, housekeepingDelaySeconds); return; } # endif diff -r 2fd6be965fcc -r c17022c1fa29 Framework/Plugins/IndexBackend.h --- a/Framework/Plugins/IndexBackend.h Wed Dec 04 17:08:41 2024 +0100 +++ b/Framework/Plugins/IndexBackend.h Wed Dec 11 15:22:08 2024 +0100 @@ -469,7 +469,8 @@ **/ static void Register(IndexBackend* backend, size_t countConnections, - unsigned int maxDatabaseRetries); + unsigned int maxDatabaseRetries, + unsigned int housekeepingDelaySeconds); static void Finalize(); diff -r 2fd6be965fcc -r c17022c1fa29 Framework/Plugins/IndexConnectionsPool.cpp --- a/Framework/Plugins/IndexConnectionsPool.cpp Wed Dec 04 17:08:41 2024 +0100 +++ b/Framework/Plugins/IndexConnectionsPool.cpp Wed Dec 11 15:22:08 2024 +0100 @@ -23,6 +23,9 @@ #include "IndexConnectionsPool.h" +#include + + namespace OrthancDatabases { class IndexConnectionsPool::ManagerReference : public Orthanc::IDynamicObject @@ -44,10 +47,44 @@ }; + void IndexConnectionsPool::HousekeepingThread(IndexConnectionsPool* that) + { + boost::posix_time::ptime lastInvocation = boost::posix_time::second_clock::local_time(); + + while (that->housekeepingContinue_) + { + if (boost::posix_time::second_clock::local_time() - lastInvocation >= that->housekeepingDelay_) + { + Accessor accessor(*that); + + try + { + accessor.GetBackend().PerformDbHousekeeping(accessor.GetManager()); + } + catch (Orthanc::OrthancException& e) + { + LOG(ERROR) << "Exception during the database housekeeping: " << e.What(); + } + catch (...) + { + LOG(ERROR) << "Native exception during the database houskeeping"; + } + + lastInvocation = boost::posix_time::second_clock::local_time(); + } + + boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); + } + } + + IndexConnectionsPool::IndexConnectionsPool(IndexBackend* backend, - size_t countConnections) : + size_t countConnections, + unsigned int houseKeepingDelaySeconds) : backend_(backend), - countConnections_(countConnections) + countConnections_(countConnections), + housekeepingContinue_(true), + housekeepingDelay_(boost::posix_time::seconds(houseKeepingDelaySeconds)) { if (countConnections == 0) { @@ -104,7 +141,15 @@ { assert(*it != NULL); availableConnections_.Enqueue(new ManagerReference(**it)); - } + } + + // Start the housekeeping thread + housekeepingContinue_ = true; + + if (backend_->HasPerformDbHousekeeping()) + { + housekeepingThread_ = boost::thread(HousekeepingThread, this); + } } else { @@ -115,6 +160,15 @@ void IndexConnectionsPool::CloseConnections() { + { + // Stop the housekeeping thread + housekeepingContinue_ = false; + if (housekeepingThread_.joinable()) + { + housekeepingThread_.join(); + } + } + boost::unique_lock lock(connectionsMutex_); if (connections_.size() != countConnections_) diff -r 2fd6be965fcc -r c17022c1fa29 Framework/Plugins/IndexConnectionsPool.h --- a/Framework/Plugins/IndexConnectionsPool.h Wed Dec 04 17:08:41 2024 +0100 +++ b/Framework/Plugins/IndexConnectionsPool.h Wed Dec 11 15:22:08 2024 +0100 @@ -29,6 +29,7 @@ #include #include +#include namespace OrthancDatabases { @@ -43,10 +44,16 @@ size_t countConnections_; std::list connections_; Orthanc::SharedMessageQueue availableConnections_; + bool housekeepingContinue_; + boost::thread housekeepingThread_; + boost::posix_time::time_duration housekeepingDelay_; + + static void HousekeepingThread(IndexConnectionsPool* that); public: IndexConnectionsPool(IndexBackend* backend /* takes ownership */, - size_t countConnections); + size_t countConnections, + unsigned int houseKeepingDelaySeconds); ~IndexConnectionsPool(); diff -r 2fd6be965fcc -r c17022c1fa29 MySQL/Plugins/IndexPlugin.cpp --- a/MySQL/Plugins/IndexPlugin.cpp Wed Dec 04 17:08:41 2024 +0100 +++ b/MySQL/Plugins/IndexPlugin.cpp Wed Dec 11 15:22:08 2024 +0100 @@ -77,11 +77,12 @@ try { const size_t countConnections = mysql.GetUnsignedIntegerValue("IndexConnectionsCount", 1); + const unsigned int housekeepingDelaySeconds = 5; // TODO - PARAMETER OrthancDatabases::MySQLParameters parameters(mysql, configuration); OrthancDatabases::IndexBackend::Register( new OrthancDatabases::MySQLIndex(context, parameters, readOnly), countConnections, - parameters.GetMaxConnectionRetries()); + parameters.GetMaxConnectionRetries(), housekeepingDelaySeconds); } catch (Orthanc::OrthancException& e) { diff -r 2fd6be965fcc -r c17022c1fa29 Odbc/Plugins/IndexPlugin.cpp --- a/Odbc/Plugins/IndexPlugin.cpp Wed Dec 04 17:08:41 2024 +0100 +++ b/Odbc/Plugins/IndexPlugin.cpp Wed Dec 11 15:22:08 2024 +0100 @@ -106,6 +106,7 @@ const unsigned int countConnections = odbc.GetUnsignedIntegerValue("IndexConnectionsCount", 1); const unsigned int maxConnectionRetries = odbc.GetUnsignedIntegerValue("MaximumConnectionRetries", 10); const unsigned int connectionRetryInterval = odbc.GetUnsignedIntegerValue("ConnectionRetryInterval", 5); + const unsigned int housekeepingDelaySeconds = 5; // TODO - PARAMETER if (connectionString.empty()) { @@ -124,7 +125,7 @@ index->SetMaxConnectionRetries(maxConnectionRetries); index->SetConnectionRetryInterval(connectionRetryInterval); - OrthancDatabases::IndexBackend::Register(index.release(), countConnections, maxConnectionRetries); + OrthancDatabases::IndexBackend::Register(index.release(), countConnections, maxConnectionRetries, housekeepingDelaySeconds); } catch (Orthanc::OrthancException& e) { diff -r 2fd6be965fcc -r c17022c1fa29 PostgreSQL/Plugins/IndexPlugin.cpp --- a/PostgreSQL/Plugins/IndexPlugin.cpp Wed Dec 04 17:08:41 2024 +0100 +++ b/PostgreSQL/Plugins/IndexPlugin.cpp Wed Dec 11 15:22:08 2024 +0100 @@ -75,11 +75,12 @@ try { const size_t countConnections = postgresql.GetUnsignedIntegerValue("IndexConnectionsCount", 50); + const unsigned int housekeepingDelaySeconds = 5; // TODO - PARAMETER OrthancDatabases::PostgreSQLParameters parameters(postgresql); OrthancDatabases::IndexBackend::Register( new OrthancDatabases::PostgreSQLIndex(context, parameters, readOnly), countConnections, - parameters.GetMaxConnectionRetries()); + parameters.GetMaxConnectionRetries(), housekeepingDelaySeconds); } catch (Orthanc::OrthancException& e) {