comparison Sources/Plugin.cpp @ 10:5d5caf89eb5b

added thread to precompute metadata
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sun, 18 Jun 2023 15:08:58 +0200
parents e8dea04df69b
children 16b9f1ff491d
comparison
equal deleted inserted replaced
9:e8dea04df69b 10:5d5caf89eb5b
26 26
27 #include <Compression/GzipCompressor.h> 27 #include <Compression/GzipCompressor.h>
28 #include <DicomFormat/DicomInstanceHasher.h> 28 #include <DicomFormat/DicomInstanceHasher.h>
29 #include <DicomFormat/DicomMap.h> 29 #include <DicomFormat/DicomMap.h>
30 #include <Logging.h> 30 #include <Logging.h>
31 #include <MultiThreading/SharedMessageQueue.h>
31 #include <SerializationToolbox.h> 32 #include <SerializationToolbox.h>
32 #include <SystemToolbox.h> 33 #include <SystemToolbox.h>
33 #include <Toolbox.h> 34 #include <Toolbox.h>
34 35
35 #include <EmbeddedResources.h> 36 #include <EmbeddedResources.h>
36 37
38 #include <boost/thread.hpp>
37 #include <boost/thread/shared_mutex.hpp> 39 #include <boost/thread/shared_mutex.hpp>
38 40
39 41
40 static const std::string METADATA_OHIF = "4202"; 42 static const std::string METADATA_OHIF = "4202";
41 static const char* const KEY_VERSION = "Version"; 43 static const char* const KEY_VERSION = "Version";
42 44 static const unsigned int MAX_INSTANCES_IN_QUEUE = 10000;
43 45
44 // Reference: https://v3-docs.ohif.org/configuration/dataSources/dicom-json 46 // Reference: https://v3-docs.ohif.org/configuration/dataSources/dicom-json
45 47
46 enum DataType 48 enum DataType
47 { 49 {
480 return false; 482 return false;
481 } 483 }
482 } 484 }
483 485
484 486
485 static ResourcesCache cache_; 487 static ResourcesCache cache_;
486 static std::string routerBasename_; 488 static std::string routerBasename_;
487 static bool useDicomWeb_; 489 static bool useDicomWeb_;
490 static boost::thread metadataThread_;
491 static Orthanc::SharedMessageQueue pendingInstances_;
492 static bool continueThread_;
488 493
489 void ServeFile(OrthancPluginRestOutput* output, 494 void ServeFile(OrthancPluginRestOutput* output,
490 const char* url, 495 const char* url,
491 const OrthancPluginHttpRequest* request) 496 const OrthancPluginHttpRequest* request)
492 { 497 {
704 709
705 OrthancPluginAnswerBuffer(context, output, s.c_str(), s.size(), "application/json"); 710 OrthancPluginAnswerBuffer(context, output, s.c_str(), s.size(), "application/json");
706 } 711 }
707 712
708 713
714 static void MetadataThread()
715 {
716 while (continueThread_)
717 {
718 std::unique_ptr<Orthanc::IDynamicObject> instance(pendingInstances_.Dequeue(100));
719 if (instance.get() != NULL)
720 {
721 const std::string instanceId = dynamic_cast<Orthanc::SingleValueObject<std::string>&>(*instance).GetValue();
722 const std::string uri = GetCacheUri(instanceId);
723
724 Json::Value instanceTags;
725 std::string metadata;
726 if (!OrthancPlugins::RestApiGetString(metadata, uri, false) &&
727 EncodeOhifInstance(instanceTags, instanceId))
728 {
729 CacheAsMetadata(instanceTags, instanceId);
730 }
731 }
732 }
733 }
734
735
709 OrthancPluginErrorCode OnChangeCallback(OrthancPluginChangeType changeType, 736 OrthancPluginErrorCode OnChangeCallback(OrthancPluginChangeType changeType,
710 OrthancPluginResourceType resourceType, 737 OrthancPluginResourceType resourceType,
711 const char* resourceId) 738 const char* resourceId)
712 { 739 {
713 try 740 try
714 { 741 {
715 if (changeType == OrthancPluginChangeType_OrthancStarted) 742 switch (changeType)
716 { 743 {
717 if (useDicomWeb_) 744 case OrthancPluginChangeType_OrthancStarted:
718 { 745 {
719 Json::Value info; 746 continueThread_ = true;
720 if (!OrthancPlugins::RestApiGet(info, "/plugins/dicom-web", false)) 747
748 if (useDicomWeb_)
721 { 749 {
722 throw Orthanc::OrthancException( 750 Json::Value info;
723 Orthanc::ErrorCode_InternalError, 751 if (!OrthancPlugins::RestApiGet(info, "/plugins/dicom-web", false))
724 "The OHIF plugin requires the DICOMweb plugin to be installed"); 752 {
753 throw Orthanc::OrthancException(
754 Orthanc::ErrorCode_InternalError,
755 "The OHIF plugin requires the DICOMweb plugin to be installed");
756 }
757
758 if (info.type() != Json::objectValue ||
759 !info.isMember("ID") ||
760 !info.isMember("Version") ||
761 info["ID"].type() != Json::stringValue ||
762 info["Version"].type() != Json::stringValue ||
763 info["ID"].asString() != "dicom-web")
764 {
765 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError,
766 "The DICOMweb plugin is required by OHIF, but is not properly installed");
767 }
725 } 768 }
726 769 else
727 if (info.type() != Json::objectValue ||
728 !info.isMember("ID") ||
729 !info.isMember("Version") ||
730 info["ID"].type() != Json::stringValue ||
731 info["Version"].type() != Json::stringValue ||
732 info["ID"].asString() != "dicom-web")
733 { 770 {
734 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, 771 metadataThread_ = boost::thread(MetadataThread);
735 "The DICOMweb plugin is required by OHIF, but is not properly installed");
736 } 772 }
737 } 773 break;
774 }
775
776 case OrthancPluginChangeType_OrthancStopped:
777 {
778 continueThread_ = false;
779
780 if (metadataThread_.joinable())
781 {
782 metadataThread_.join();
783 }
784 break;
785 }
786
787 case OrthancPluginChangeType_NewInstance:
788 {
789 if (metadataThread_.joinable() &&
790 pendingInstances_.GetSize() < MAX_INSTANCES_IN_QUEUE)
791 {
792 pendingInstances_.Enqueue(new Orthanc::SingleValueObject<std::string>(resourceId));
793 }
794
795 break;
796 }
797
798 default:
799 break;
738 } 800 }
739 } 801 }
740 catch (Orthanc::OrthancException& e) 802 catch (Orthanc::OrthancException& e)
741 { 803 {
742 LOG(ERROR) << "Exception: " << e.What(); 804 LOG(ERROR) << "Exception: " << e.What();