changeset 601:c17022c1fa29 find-refactoring

added a housekeeping thread
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 11 Dec 2024 15:22:08 +0100
parents 2fd6be965fcc
children ef14f978fed1
files Framework/Plugins/DatabaseBackendAdapterV3.cpp Framework/Plugins/DatabaseBackendAdapterV3.h Framework/Plugins/DatabaseBackendAdapterV4.cpp Framework/Plugins/DatabaseBackendAdapterV4.h Framework/Plugins/IndexBackend.cpp Framework/Plugins/IndexBackend.h Framework/Plugins/IndexConnectionsPool.cpp Framework/Plugins/IndexConnectionsPool.h MySQL/Plugins/IndexPlugin.cpp Odbc/Plugins/IndexPlugin.cpp PostgreSQL/Plugins/IndexPlugin.cpp
diffstat 11 files changed, 87 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- 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<IndexBackend> protection(backend);
     
@@ -1905,7 +1906,7 @@
  
     if (OrthancPluginRegisterDatabaseBackendV3(
           context, &params, 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");
--- 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();
   };
--- 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<IndexConnectionsPool> pool(new IndexConnectionsPool(backend, countConnections));
+    std::unique_ptr<IndexConnectionsPool> pool(new IndexConnectionsPool(backend, countConnections, housekeepingDelaySeconds));
     
     if (isBackendInUse_)
     {
--- 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();
   };
--- 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
--- 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();
 
--- 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 <Logging.h>
+
+
 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<boost::shared_mutex>  lock(connectionsMutex_);
 
     if (connections_.size() != countConnections_)
--- 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 <MultiThreading/SharedMessageQueue.h>
 
 #include <list>
+#include <boost/thread.hpp>
 
 namespace OrthancDatabases
 {
@@ -43,10 +44,16 @@
     size_t                         countConnections_;
     std::list<DatabaseManager*>    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();
 
--- 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)
     {
--- 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)
     {
--- 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)
     {