changeset 83:e90266cc3d9b

new PeerCommitTimeout configuration
author Alain Mazy <am@orthanc.team>
date Mon, 12 May 2025 13:02:53 +0200
parents 2fd46562dc57
children 3a460db3e6cb
files Framework/PushMode/PushJob.cpp Framework/PushMode/PushJob.h Framework/TransferToolbox.cpp Framework/TransferToolbox.h NEWS Plugin/Plugin.cpp Plugin/PluginContext.cpp Plugin/PluginContext.h Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h
diffstat 10 files changed, 132 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/PushMode/PushJob.cpp	Thu May 08 09:25:48 2025 +0200
+++ b/Framework/PushMode/PushJob.cpp	Mon May 12 13:02:53 2025 +0200
@@ -60,7 +60,7 @@
 
       if (isCommit_)
       {
-        success = DoPostPeer(answer, job_.peers_, job_.peerIndex_, transactionUri_ + "/commit", "", job_.maxHttpRetries_, headers);
+        success = DoPostPeer(answer, job_.peers_, job_.peerIndex_, transactionUri_ + "/commit", "", job_.maxHttpRetries_, headers, job_.commitTimeout_);
       }
       else
       {
@@ -263,13 +263,15 @@
                    OrthancInstancesCache& cache,
                    size_t threadsCount,
                    size_t targetBucketSize,
-                   unsigned int maxHttpRetries) :
+                   unsigned int maxHttpRetries,
+                   unsigned int commitTimeout) :
     StatefulOrthancJob(JOB_TYPE_PUSH),
     cache_(cache),
     query_(query),
     threadsCount_(threadsCount),
     targetBucketSize_(targetBucketSize),
-    maxHttpRetries_(maxHttpRetries)
+    maxHttpRetries_(maxHttpRetries),
+    commitTimeout_(commitTimeout)
   {
     if (!peers_.LookupName(peerIndex_, query_.GetPeer()))
     {
--- a/Framework/PushMode/PushJob.h	Thu May 08 09:25:48 2025 +0200
+++ b/Framework/PushMode/PushJob.h	Mon May 12 13:02:53 2025 +0200
@@ -41,6 +41,7 @@
     OrthancPeers             peers_;
     size_t                   peerIndex_;
     unsigned int             maxHttpRetries_;
+    unsigned int             commitTimeout_;
  
     virtual StateUpdate* CreateInitialState(JobInfo& info);
     
@@ -49,6 +50,7 @@
             OrthancInstancesCache& cache,
             size_t threadsCount,
             size_t targetBucketSize,
-            unsigned int maxHttpRetries);
+            unsigned int maxHttpRetries,
+            unsigned int commitTimeout);
   };
 }
--- a/Framework/TransferToolbox.cpp	Thu May 08 09:25:48 2025 +0200
+++ b/Framework/TransferToolbox.cpp	Mon May 12 13:02:53 2025 +0200
@@ -86,6 +86,45 @@
                   const std::string& uri,
                   const std::string& body,
                   unsigned int maxRetries,
+                  const std::map<std::string, std::string>& headers,
+                  unsigned int timeout
+)
+  {
+    unsigned int retry = 0;
+
+    for (;;)
+    {
+      try
+      {
+        if (peers.DoPost(answer, peerIndex, uri, body, headers, timeout))
+        {
+          return true;
+        }
+      }
+      catch (Orthanc::OrthancException&)
+      {
+      }
+
+      if (retry >= maxRetries)
+      {
+        return false;
+      }
+      else
+      {
+        // Wait 1 second before retrying
+        boost::this_thread::sleep(boost::posix_time::seconds(1));
+        retry++;
+      }
+    }
+  }
+
+
+  bool DoPostPeer(Json::Value& answer,
+                  const OrthancPeers& peers,
+                  size_t peerIndex,
+                  const std::string& uri,
+                  const std::string& body,
+                  unsigned int maxRetries,
                   const std::map<std::string, std::string>& headers
 )
   {
--- a/Framework/TransferToolbox.h	Thu May 08 09:25:48 2025 +0200
+++ b/Framework/TransferToolbox.h	Mon May 12 13:02:53 2025 +0200
@@ -90,6 +90,15 @@
 
   bool DoPostPeer(Json::Value& answer,
                   const OrthancPeers& peers,
+                  size_t peerIndex,
+                  const std::string& uri,
+                  const std::string& body,
+                  unsigned int maxRetries,
+                  const std::map<std::string, std::string>& headers,
+                  unsigned int timeout);
+
+  bool DoPostPeer(Json::Value& answer,
+                  const OrthancPeers& peers,
                   const std::string& peerName,
                   const std::string& uri,
                   const std::string& body,
--- a/NEWS	Thu May 08 09:25:48 2025 +0200
+++ b/NEWS	Mon May 12 13:02:53 2025 +0200
@@ -6,6 +6,10 @@
 
 * now setting "Content-Type" HTTP headers in outgoing POST requests.
   (https://discourse.orthanc-server.org/t/transfer-accelerator-plugin-http-header-compatibility/5725)
+* new "PeerCommitTimeout" configuration to configure the HTTP Timeout when committing
+  a push transfer.  During that time, the remote peer plugin must import all files into Orthanc
+  which can take a significant time if the transfer is large.  The default value is
+  set to 600 seconds.
 * Maintenance: Use Orthanc SDK 1.12.4 by default to benefit from more detailed logging.
 
 
--- a/Plugin/Plugin.cpp	Thu May 08 09:25:48 2025 +0200
+++ b/Plugin/Plugin.cpp	Mon May 12 13:02:53 2025 +0200
@@ -486,7 +486,8 @@
     SubmitJob(output, new OrthancPlugins::PushJob(query, context.GetCache(),
                                                   context.GetThreadsCount(),
                                                   context.GetTargetBucketSize(),
-                                                  context.GetMaxHttpRetries()),
+                                                  context.GetMaxHttpRetries(),
+                                                  context.GetPeerCommitTimeout()),
               query.GetPriority());
   }
 }
@@ -535,7 +536,8 @@
                                               context.GetCache(),
                                               context.GetThreadsCount(),
                                               context.GetTargetBucketSize(),
-                                              context.GetMaxHttpRetries()));
+                                              context.GetMaxHttpRetries(),
+                                              context.GetPeerCommitTimeout()));
       }
 
       if (job.get() == NULL)
@@ -652,6 +654,7 @@
       size_t memoryCacheSize = 512;    // In MB
       unsigned int maxHttpRetries = 0;
       unsigned int peerConnectivityTimeout = 2;
+      unsigned int peerCommitTimeout = 600;
     
       {
         OrthancPlugins::OrthancConfiguration config;
@@ -667,11 +670,12 @@
           maxPushTransactions = plugin.GetUnsignedIntegerValue("MaxPushTransactions", maxPushTransactions);
           maxHttpRetries = plugin.GetUnsignedIntegerValue("MaxHttpRetries", maxHttpRetries);
           peerConnectivityTimeout = plugin.GetUnsignedIntegerValue("PeerConnectivityTimeout", peerConnectivityTimeout);
+          peerCommitTimeout = plugin.GetUnsignedIntegerValue("PeerCommitTimeout", peerCommitTimeout);
         }
       }
 
       OrthancPlugins::PluginContext::Initialize(threadsCount, targetBucketSize * KB, maxPushTransactions,
-                                                memoryCacheSize * MB, maxHttpRetries, peerConnectivityTimeout);
+                                                memoryCacheSize * MB, maxHttpRetries, peerConnectivityTimeout, peerCommitTimeout);
     
       OrthancPlugins::RegisterRestCallback<ServeChunks>
         (std::string(URI_CHUNKS) + "/([.0-9a-f-]+)", true);
--- a/Plugin/PluginContext.cpp	Thu May 08 09:25:48 2025 +0200
+++ b/Plugin/PluginContext.cpp	Mon May 12 13:02:53 2025 +0200
@@ -32,14 +32,16 @@
                                size_t maxPushTransactions,
                                size_t memoryCacheSize,
                                unsigned int maxHttpRetries,
-                               unsigned int peerConnectivityTimeout) :
+                               unsigned int peerConnectivityTimeout,
+                               unsigned int peerCommitTimeout) :
     pushTransactions_(maxPushTransactions),
     semaphore_(threadsCount),
     pluginUuid_(Orthanc::Toolbox::GenerateUuid()),
     threadsCount_(threadsCount),
     targetBucketSize_(targetBucketSize),
     maxHttpRetries_(maxHttpRetries),
-    peerConnectivityTimeout_(peerConnectivityTimeout)
+    peerConnectivityTimeout_(peerConnectivityTimeout),
+    peerCommitTimeout_(peerCommitTimeout)
   {
     cache_.SetMaxMemorySize(memoryCacheSize);
 
@@ -54,6 +56,8 @@
               << maxHttpRetries_ << " time(s) if some HTTP query fails";
     LOG(INFO) << "Transfers accelerator will use "
               << peerConnectivityTimeout_ << " seconds as a timeout when checking peers connectivity";
+    LOG(INFO) << "Transfers accelerator will use "
+              << peerCommitTimeout_ << " seconds as a timeout when committing push transfer";
   }
 
 
@@ -69,10 +73,11 @@
                                  size_t maxPushTransactions,
                                  size_t memoryCacheSize,
                                  unsigned int maxHttpRetries,
-                                 unsigned int peerConnectivityTimeout)
+                                 unsigned int peerConnectivityTimeout,
+                                 unsigned int peerCommitTimeout)
   {
     GetSingleton().reset(new PluginContext(threadsCount, targetBucketSize,
-                                           maxPushTransactions, memoryCacheSize, maxHttpRetries, peerConnectivityTimeout));
+                                           maxPushTransactions, memoryCacheSize, maxHttpRetries, peerConnectivityTimeout, peerCommitTimeout));
   }
 
   
--- a/Plugin/PluginContext.h	Thu May 08 09:25:48 2025 +0200
+++ b/Plugin/PluginContext.h	Mon May 12 13:02:53 2025 +0200
@@ -45,13 +45,15 @@
     size_t                   targetBucketSize_;
     unsigned int             maxHttpRetries_;
     unsigned int             peerConnectivityTimeout_;
+    unsigned int             peerCommitTimeout_;
   
     PluginContext(size_t threadsCount,
                   size_t targetBucketSize,
                   size_t maxPushTransactions,
                   size_t memoryCacheSize,
                   unsigned int maxHttpRetries,
-                  unsigned int peerConnectivityTimeout);
+                  unsigned int peerConnectivityTimeout,
+                  unsigned int peerCommitTimeout);
 
     static std::unique_ptr<PluginContext>& GetSingleton();
   
@@ -96,12 +98,18 @@
       return peerConnectivityTimeout_;
     }
 
+    unsigned int GetPeerCommitTimeout() const
+    {
+      return peerCommitTimeout_;
+    }
+
     static void Initialize(size_t threadsCount,
                            size_t targetBucketSize,
                            size_t maxPushTransactions,
                            size_t memoryCacheSize,
                            unsigned int maxHttpRetries,
-                           unsigned int peerConnectivityTimeout);
+                           unsigned int peerConnectivityTimeout,
+                           unsigned int peerCommitTimeout);
   
     static PluginContext& GetInstance();
 
--- a/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp	Thu May 08 09:25:48 2025 +0200
+++ b/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp	Mon May 12 13:02:53 2025 +0200
@@ -2052,6 +2052,26 @@
             DoPost(target, index, uri, body, headers));
   }
 
+  bool OrthancPeers::DoPost(Json::Value& target,
+                            size_t index,
+                            const std::string& uri,
+                            const std::string& body,
+                            const HttpHeaders& headers, 
+                            unsigned int timeout) const
+  {
+    MemoryBuffer buffer;
+
+    if (DoPost(buffer, index, uri, body, headers, timeout))
+    {
+      buffer.ToJson(target);
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
 
   bool OrthancPeers::DoPost(Json::Value& target,
                             size_t index,
@@ -2099,6 +2119,17 @@
                             const std::string& body,
                             const HttpHeaders& headers) const
   {
+    return DoPost(target, index, uri, body, headers, timeout_);
+  }
+
+
+  bool OrthancPeers::DoPost(MemoryBuffer& target,
+                            size_t index,
+                            const std::string& uri,
+                            const std::string& body,
+                            const HttpHeaders& headers,
+                            unsigned int timeout) const
+  {
     if (index >= index_.size())
     {
       ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_ParameterOutOfRange);
@@ -2117,7 +2148,7 @@
     OrthancPluginErrorCode code = OrthancPluginCallPeerApi
       (GetGlobalContext(), *answer, NULL, &status, peers_,
        static_cast<uint32_t>(index), OrthancPluginHttpMethod_Post, uri.c_str(),
-       pluginHeaders.GetSize(), pluginHeaders.GetKeys(), pluginHeaders.GetValues(), body.empty() ? NULL : body.c_str(), body.size(), timeout_);
+       pluginHeaders.GetSize(), pluginHeaders.GetKeys(), pluginHeaders.GetValues(), body.empty() ? NULL : body.c_str(), body.size(), timeout);
 
     if (code == OrthancPluginErrorCode_Success)
     {
--- a/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h	Thu May 08 09:25:48 2025 +0200
+++ b/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h	Mon May 12 13:02:53 2025 +0200
@@ -855,6 +855,13 @@
                 const HttpHeaders& headers) const;
 
     bool DoPost(MemoryBuffer& target,
+                size_t index,
+                const std::string& uri,
+                const std::string& body,
+                const HttpHeaders& headers,
+                unsigned int timeout) const;
+
+    bool DoPost(MemoryBuffer& target,
                 const std::string& name,
                 const std::string& uri,
                 const std::string& body,
@@ -867,6 +874,13 @@
                 const HttpHeaders& headers) const;
 
     bool DoPost(Json::Value& target,
+                size_t index,
+                const std::string& uri,
+                const std::string& body,
+                const HttpHeaders& headers,
+                unsigned int timeout) const;
+
+    bool DoPost(Json::Value& target,
                 const std::string& name,
                 const std::string& uri,
                 const std::string& body,