changeset 6641:6460dcea0aa5

use ThreadedInstancesLoader for C-Get
author Alain Mazy <am@orthanc.team>
date Mon, 30 Mar 2026 10:46:07 +0200
parents e4a22c4a3512
children 7c587343e308
files NEWS OrthancServer/Sources/OrthancGetRequestHandler.cpp OrthancServer/Sources/OrthancGetRequestHandler.h
diffstat 3 files changed, 29 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Mon Mar 30 10:02:22 2026 +0200
+++ b/NEWS	Mon Mar 30 10:46:07 2026 +0200
@@ -9,6 +9,7 @@
   - downloading zip archive/media,
   - performing a C-Store to a remote modality
   - performing a peer transfer to a remote Orthanc.
+  - responding to a C-Get request from a remote modality.
   Note: the old "ZipLoaderThreads" configuration is still available for backward 
         compatibility reasons.
 * When performing a C-Store or a peer transfer, the instances are now 
@@ -16,7 +17,6 @@
   a random order in previous Orthanc versions.
 TODO before release: - reconfigure the instancesLoader when unserializing a C-Store or peer job
                      - serialize the ParentResources in C-Store and peer job
-                     - use ThreadedInstancesLoader in OrthancGetRequestHandler
 * New experimental configuration "PatientLevelEnabled".
 
 TODO before release: re-enable test_content_disposition
--- a/OrthancServer/Sources/OrthancGetRequestHandler.cpp	Mon Mar 30 10:02:22 2026 +0200
+++ b/OrthancServer/Sources/OrthancGetRequestHandler.cpp	Mon Mar 30 10:46:07 2026 +0200
@@ -30,6 +30,7 @@
 #include "OrthancConfiguration.h"
 #include "ServerContext.h"
 #include "ServerJobs/DicomModalityStoreJob.h"
+#include "ServerJobs/ThreadedInstancesLoader.h"
 
 #include <dcmtk/dcmdata/dcdeftag.h>
 #include <dcmtk/dcmdata/dcfilefo.h>
@@ -59,15 +60,20 @@
 
   bool OrthancGetRequestHandler::DoNext(T_ASC_Association* assoc)
   {
-    if (position_ >= instances_.size())
+    if (position_ >= instancesIds_.size())
     {
       throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
     
-    const std::string& id = instances_[position_++];
+    if (instancesLoader_.get() == NULL)
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+
+    const std::string& id = instancesIds_[position_++];
 
     std::string dicom;
-    context_.ReadDicom(dicom, id);
+    instancesLoader_->GetDicom(dicom, id);
     
     if (dicom.empty())
     {
@@ -544,7 +550,8 @@
     localAet_ = context_.GetDefaultLocalApplicationEntityTitle();
     position_ = 0;
     originatorAet_ = originatorAet;
-    
+    unsigned int loaderThreads = 1;
+
     {
       OrthancConfiguration::ReaderLock lock;
 
@@ -567,21 +574,24 @@
         throw OrthancException(ErrorCode_InexistentItem,
                                "C-GET: Rejecting SCU request from unknown modality with AET: " + originatorAet);
       }
+
+      loaderThreads = lock.GetConfiguration().GetLoaderThreads();
     }
 
+    instancesLoader_.reset(new ThreadedInstancesLoader(context_, loaderThreads, false, DicomTransferSyntax_BigEndianExplicit /* dummy unused value */, 0, "CGET"));
+
     for (std::list<std::string>::const_iterator
-           resource = publicIds.begin(); resource != publicIds.end(); ++resource)
+           resourceId = publicIds.begin(); resourceId != publicIds.end(); ++resourceId)
     {
-      CLOG(INFO, DICOM) << "C-GET: Sending resource " << *resource
+      CLOG(INFO, DICOM) << "C-GET: Sending resource " << *resourceId
                         << " to modality \"" << originatorAet << "\"";
-      
-      std::list<std::string> tmp;
-      context_.GetIndex().GetChildInstances(tmp, *resource);
-      
-      instances_.reserve(tmp.size());
-      for (std::list<std::string>::iterator it = tmp.begin(); it != tmp.end(); ++it)
+
+      std::vector<FileInfo> filesInfo;
+      context_.GetOrderedChildInstances(instancesIds_, filesInfo, *resourceId, level);
+
+      for (size_t i = 0; i < instancesIds_.size(); ++i)
       {
-        instances_.push_back(*it);
+        instancesLoader_->PrepareDicom(instancesIds_[i], filesInfo[i]);
       }
     }
 
--- a/OrthancServer/Sources/OrthancGetRequestHandler.h	Mon Mar 30 10:02:22 2026 +0200
+++ b/OrthancServer/Sources/OrthancGetRequestHandler.h	Mon Mar 30 10:46:07 2026 +0200
@@ -35,16 +35,18 @@
 namespace Orthanc
 {
   class ServerContext;
+  class ThreadedInstancesLoader;
   
   class OrthancGetRequestHandler : public IGetRequestHandler
   {
   private:
     ServerContext& context_;
     std::string localAet_;
-    std::vector<std::string> instances_;
+    std::vector<std::string> instancesIds_;
     size_t position_;
     std::string originatorAet_;
-    
+    std::unique_ptr<ThreadedInstancesLoader> instancesLoader_;
+
     unsigned int completedCount_;
     unsigned int warningCount_;
     unsigned int failedCount_;
@@ -78,7 +80,7 @@
     
     virtual unsigned int GetSubOperationCount() const ORTHANC_OVERRIDE
     {
-      return static_cast<unsigned int>(instances_.size());
+      return static_cast<unsigned int>(instancesIds_.size());
     }
     
     virtual unsigned int GetCompletedCount() const ORTHANC_OVERRIDE