comparison OrthancServer/Sources/OrthancRestApi/OrthancRestArchive.cpp @ 4797:4e765c18ace7 storage-cache

enable using multiple threads to load instances when generating zip archive/media
author Alain Mazy <am@osimis.io>
date Thu, 07 Oct 2021 13:31:36 +0200
parents b3957ddd88f1
children 70d2a97ca8cb 7053502fbf97
comparison
equal deleted inserted replaced
4792:434843934307 4797:4e765c18ace7
49 namespace Orthanc 49 namespace Orthanc
50 { 50 {
51 static const char* const KEY_RESOURCES = "Resources"; 51 static const char* const KEY_RESOURCES = "Resources";
52 static const char* const KEY_EXTENDED = "Extended"; 52 static const char* const KEY_EXTENDED = "Extended";
53 static const char* const KEY_TRANSCODE = "Transcode"; 53 static const char* const KEY_TRANSCODE = "Transcode";
54 54
55 static const char* const CONFIG_LOADER_THREADS = "ZipLoaderThreads";
56
55 static void AddResourcesOfInterestFromArray(ArchiveJob& job, 57 static void AddResourcesOfInterestFromArray(ArchiveJob& job,
56 const Json::Value& resources) 58 const Json::Value& resources)
57 { 59 {
58 if (resources.type() != Json::arrayValue) 60 if (resources.type() != Json::arrayValue)
59 { 61 {
121 static void GetJobParameters(bool& synchronous, /* out */ 123 static void GetJobParameters(bool& synchronous, /* out */
122 bool& extended, /* out */ 124 bool& extended, /* out */
123 bool& transcode, /* out */ 125 bool& transcode, /* out */
124 DicomTransferSyntax& syntax, /* out */ 126 DicomTransferSyntax& syntax, /* out */
125 int& priority, /* out */ 127 int& priority, /* out */
128 unsigned int& loaderThreads, /* out */
126 const Json::Value& body, /* in */ 129 const Json::Value& body, /* in */
127 const bool defaultExtended /* in */) 130 const bool defaultExtended /* in */)
128 { 131 {
129 synchronous = OrthancRestApi::IsSynchronousJobRequest 132 synchronous = OrthancRestApi::IsSynchronousJobRequest
130 (true /* synchronous by default */, body); 133 (true /* synchronous by default */, body);
149 } 152 }
150 else 153 else
151 { 154 {
152 transcode = false; 155 transcode = false;
153 } 156 }
157
158 {
159 OrthancConfiguration::ReaderLock lock;
160 loaderThreads = lock.GetConfiguration().GetUnsignedIntegerParameter(CONFIG_LOADER_THREADS, 0); // New in Orthanc 1.9.8
161 }
162
154 } 163 }
155 164
156 165
157 namespace 166 namespace
158 { 167 {
552 if (call.ParseJsonRequest(body)) 561 if (call.ParseJsonRequest(body))
553 { 562 {
554 bool synchronous, extended, transcode; 563 bool synchronous, extended, transcode;
555 DicomTransferSyntax transferSyntax; 564 DicomTransferSyntax transferSyntax;
556 int priority; 565 int priority;
566 unsigned int loaderThreads;
557 GetJobParameters(synchronous, extended, transcode, transferSyntax, 567 GetJobParameters(synchronous, extended, transcode, transferSyntax,
558 priority, body, DEFAULT_IS_EXTENDED); 568 priority, loaderThreads, body, DEFAULT_IS_EXTENDED);
559 569
560 std::unique_ptr<ArchiveJob> job(new ArchiveJob(context, IS_MEDIA, extended)); 570 std::unique_ptr<ArchiveJob> job(new ArchiveJob(context, IS_MEDIA, extended));
561 AddResourcesOfInterest(*job, body); 571 AddResourcesOfInterest(*job, body);
562 572
563 if (transcode) 573 if (transcode)
564 { 574 {
565 job->SetTranscode(transferSyntax); 575 job->SetTranscode(transferSyntax);
566 } 576 }
567 577
578 job->SetLoaderThreads(loaderThreads);
579
568 SubmitJob(call.GetOutput(), context, job, priority, synchronous, "Archive.zip"); 580 SubmitJob(call.GetOutput(), context, job, priority, synchronous, "Archive.zip");
569 } 581 }
570 else 582 else
571 { 583 {
572 throw OrthancException(ErrorCode_BadFileFormat, 584 throw OrthancException(ErrorCode_BadFileFormat,
576 588
577 589
578 template <bool IS_MEDIA> 590 template <bool IS_MEDIA>
579 static void CreateSingleGet(RestApiGetCall& call) 591 static void CreateSingleGet(RestApiGetCall& call)
580 { 592 {
593 static const char* const TRANSCODE = "transcode";
594
581 if (call.IsDocumentation()) 595 if (call.IsDocumentation())
582 { 596 {
583 ResourceType t = StringToResourceType(call.GetFullUri()[0].c_str()); 597 ResourceType t = StringToResourceType(call.GetFullUri()[0].c_str());
584 std::string r = GetResourceTypeText(t, false /* plural */, false /* upper case */); 598 std::string r = GetResourceTypeText(t, false /* plural */, false /* upper case */);
585 std::string m = (IS_MEDIA ? "DICOMDIR media" : "ZIP archive"); 599 std::string m = (IS_MEDIA ? "DICOMDIR media" : "ZIP archive");
589 .SetDescription("Synchronously create a " + m + " containing the DICOM " + r + 603 .SetDescription("Synchronously create a " + m + " containing the DICOM " + r +
590 " whose Orthanc identifier is provided in the URL. This flavor is synchronous, " 604 " whose Orthanc identifier is provided in the URL. This flavor is synchronous, "
591 "which might *not* be desirable to archive large amount of data, as it might " 605 "which might *not* be desirable to archive large amount of data, as it might "
592 "lead to network timeouts. Prefer the asynchronous version using `POST` method.") 606 "lead to network timeouts. Prefer the asynchronous version using `POST` method.")
593 .SetUriArgument("id", "Orthanc identifier of the " + r + " of interest") 607 .SetUriArgument("id", "Orthanc identifier of the " + r + " of interest")
594 .SetHttpGetArgument("transcode", RestApiCallDocumentation::Type_String, 608 .SetHttpGetArgument(TRANSCODE, RestApiCallDocumentation::Type_String,
595 "If present, the DICOM files in the archive will be transcoded to the provided " 609 "If present, the DICOM files in the archive will be transcoded to the provided "
596 "transfer syntax: https://book.orthanc-server.com/faq/transcoding.html", false) 610 "transfer syntax: https://book.orthanc-server.com/faq/transcoding.html", false)
597 .AddAnswerType(MimeType_Zip, "ZIP file containing the archive"); 611 .AddAnswerType(MimeType_Zip, "ZIP file containing the archive");
598 if (IS_MEDIA) 612 if (IS_MEDIA)
599 { 613 {
619 } 633 }
620 634
621 std::unique_ptr<ArchiveJob> job(new ArchiveJob(context, IS_MEDIA, extended)); 635 std::unique_ptr<ArchiveJob> job(new ArchiveJob(context, IS_MEDIA, extended));
622 job->AddResource(id); 636 job->AddResource(id);
623 637
624 static const char* const TRANSCODE = "transcode";
625 if (call.HasArgument(TRANSCODE)) 638 if (call.HasArgument(TRANSCODE))
626 { 639 {
627 job->SetTranscode(GetTransferSyntax(call.GetArgument(TRANSCODE, ""))); 640 job->SetTranscode(GetTransferSyntax(call.GetArgument(TRANSCODE, "")));
641 }
642
643 {
644 OrthancConfiguration::ReaderLock lock;
645 unsigned int loaderThreads = lock.GetConfiguration().GetUnsignedIntegerParameter(CONFIG_LOADER_THREADS, 0); // New in Orthanc 1.9.8
646 job->SetLoaderThreads(loaderThreads);
628 } 647 }
629 648
630 SubmitJob(call.GetOutput(), context, job, 0 /* priority */, 649 SubmitJob(call.GetOutput(), context, job, 0 /* priority */,
631 true /* synchronous */, id + ".zip"); 650 true /* synchronous */, id + ".zip");
632 } 651 }
658 if (call.ParseJsonRequest(body)) 677 if (call.ParseJsonRequest(body))
659 { 678 {
660 bool synchronous, extended, transcode; 679 bool synchronous, extended, transcode;
661 DicomTransferSyntax transferSyntax; 680 DicomTransferSyntax transferSyntax;
662 int priority; 681 int priority;
682 unsigned int loaderThreads;
663 GetJobParameters(synchronous, extended, transcode, transferSyntax, 683 GetJobParameters(synchronous, extended, transcode, transferSyntax,
664 priority, body, false /* by default, not extented */); 684 priority, loaderThreads, body, false /* by default, not extented */);
665 685
666 std::unique_ptr<ArchiveJob> job(new ArchiveJob(context, IS_MEDIA, extended)); 686 std::unique_ptr<ArchiveJob> job(new ArchiveJob(context, IS_MEDIA, extended));
667 job->AddResource(id); 687 job->AddResource(id);
668 688
669 if (transcode) 689 if (transcode)
670 { 690 {
671 job->SetTranscode(transferSyntax); 691 job->SetTranscode(transferSyntax);
672 } 692 }
693
694 job->SetLoaderThreads(loaderThreads);
673 695
674 SubmitJob(call.GetOutput(), context, job, priority, synchronous, id + ".zip"); 696 SubmitJob(call.GetOutput(), context, job, priority, synchronous, id + ".zip");
675 } 697 }
676 else 698 else
677 { 699 {