# HG changeset patch # User Alain Mazy # Date 1774860367 -7200 # Node ID 6460dcea0aa52ed72dfd106e27781f07903ab5fe # Parent e4a22c4a351293b3e77c930746bd8fc9a40868cf use ThreadedInstancesLoader for C-Get diff -r e4a22c4a3512 -r 6460dcea0aa5 NEWS --- 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 diff -r e4a22c4a3512 -r 6460dcea0aa5 OrthancServer/Sources/OrthancGetRequestHandler.cpp --- 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 #include @@ -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::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 tmp; - context_.GetIndex().GetChildInstances(tmp, *resource); - - instances_.reserve(tmp.size()); - for (std::list::iterator it = tmp.begin(); it != tmp.end(); ++it) + + std::vector 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]); } } diff -r e4a22c4a3512 -r 6460dcea0aa5 OrthancServer/Sources/OrthancGetRequestHandler.h --- 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 instances_; + std::vector instancesIds_; size_t position_; std::string originatorAet_; - + std::unique_ptr instancesLoader_; + unsigned int completedCount_; unsigned int warningCount_; unsigned int failedCount_; @@ -78,7 +80,7 @@ virtual unsigned int GetSubOperationCount() const ORTHANC_OVERRIDE { - return static_cast(instances_.size()); + return static_cast(instancesIds_.size()); } virtual unsigned int GetCompletedCount() const ORTHANC_OVERRIDE