Mercurial > hg > orthanc
comparison UnitTestsSources/MultiThreadingTests.cpp @ 2570:2e879c796ec7 jobs
JobsRegistry::SubmitAndWait(), StoreScuJob
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 07 May 2018 21:42:04 +0200 |
parents | 2af17cd5eb1f |
children | 3372c5255333 |
comparison
equal
deleted
inserted
replaced
2569:2af17cd5eb1f | 2570:2e879c796ec7 |
---|---|
261 count_(0), | 261 count_(0), |
262 steps_(4) | 262 steps_(4) |
263 { | 263 { |
264 } | 264 } |
265 | 265 |
266 virtual void Start() | |
267 { | |
268 } | |
269 | |
266 virtual JobStepResult* ExecuteStep() | 270 virtual JobStepResult* ExecuteStep() |
267 { | 271 { |
268 boost::this_thread::sleep(boost::posix_time::milliseconds(50)); | 272 boost::this_thread::sleep(boost::posix_time::milliseconds(10)); |
269 | 273 |
270 if (count_ == steps_ - 1) | 274 if (count_ == steps_ - 1) |
271 { | 275 { |
272 return new JobStepResult(result_); | 276 return new JobStepResult(result_); |
273 } | 277 } |
596 | 600 |
597 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Success)); | 601 ASSERT_TRUE(CheckState(registry, id, Orthanc::JobState_Success)); |
598 } | 602 } |
599 | 603 |
600 | 604 |
605 | |
606 #include "../OrthancServer/ServerContext.h" | |
607 | |
608 namespace Orthanc | |
609 { | |
610 class InstancesIteratorJob : public IJob | |
611 { | |
612 private: | |
613 bool started_; | |
614 std::vector<std::string> instances_; | |
615 size_t position_; | |
616 | |
617 public: | |
618 InstancesIteratorJob() : | |
619 started_(false), | |
620 position_(0) | |
621 { | |
622 } | |
623 | |
624 void Reserve(size_t size) | |
625 { | |
626 if (started_) | |
627 { | |
628 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
629 } | |
630 else | |
631 { | |
632 instances_.reserve(size); | |
633 } | |
634 } | |
635 | |
636 void AddInstance(const std::string& instance) | |
637 { | |
638 if (started_) | |
639 { | |
640 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
641 } | |
642 else | |
643 { | |
644 instances_.push_back(instance); | |
645 } | |
646 } | |
647 | |
648 virtual void Start() | |
649 { | |
650 started_ = true; | |
651 } | |
652 | |
653 virtual float GetProgress() | |
654 { | |
655 if (instances_.size() == 0) | |
656 { | |
657 return 0; | |
658 } | |
659 else | |
660 { | |
661 return (static_cast<float>(position_) / | |
662 static_cast<float>(instances_.size())); | |
663 } | |
664 } | |
665 | |
666 bool IsStarted() const | |
667 { | |
668 return started_; | |
669 } | |
670 | |
671 bool IsDone() const | |
672 { | |
673 if (instances_.size() == 0) | |
674 { | |
675 return true; | |
676 } | |
677 else | |
678 { | |
679 return (position_ == instances_.size() - 1); | |
680 } | |
681 } | |
682 | |
683 void Next() | |
684 { | |
685 if (IsDone()) | |
686 { | |
687 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
688 } | |
689 else | |
690 { | |
691 position_ += 1; | |
692 } | |
693 } | |
694 | |
695 const std::string& GetCurrentInstance() const | |
696 { | |
697 if (IsDone()) | |
698 { | |
699 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
700 } | |
701 else | |
702 { | |
703 return instances_[position_]; | |
704 } | |
705 } | |
706 }; | |
707 | |
708 | |
709 class StoreScuJob : public InstancesIteratorJob | |
710 { | |
711 private: | |
712 ServerContext& context_; | |
713 std::string localAet_; | |
714 RemoteModalityParameters remote_; | |
715 bool permissive_; | |
716 std::string moveOriginatorAet_; | |
717 uint16_t moveOriginatorId_; | |
718 std::auto_ptr<DicomUserConnection> connection_; | |
719 std::set<std::string> failedInstances_; | |
720 | |
721 void Open() | |
722 { | |
723 if (connection_.get() == NULL) | |
724 { | |
725 connection_.reset(new DicomUserConnection); | |
726 connection_->SetLocalApplicationEntityTitle(localAet_); | |
727 connection_->SetRemoteModality(remote_); | |
728 connection_->Open(); | |
729 } | |
730 } | |
731 | |
732 public: | |
733 StoreScuJob(ServerContext& context) : | |
734 context_(context), | |
735 localAet_("ORTHANC"), | |
736 permissive_(false), | |
737 moveOriginatorId_(0) // By default, not a C-MOVE | |
738 { | |
739 } | |
740 | |
741 const std::string& GetLocalAet() const | |
742 { | |
743 return localAet_; | |
744 } | |
745 | |
746 void SetLocalAet(const std::string& aet) | |
747 { | |
748 if (IsStarted()) | |
749 { | |
750 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
751 } | |
752 else | |
753 { | |
754 localAet_ = aet; | |
755 } | |
756 } | |
757 | |
758 const RemoteModalityParameters& GetRemoteModality() const | |
759 { | |
760 return remote_; | |
761 } | |
762 | |
763 void SetRemoteModality(const RemoteModalityParameters& remote) | |
764 { | |
765 if (IsStarted()) | |
766 { | |
767 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
768 } | |
769 else | |
770 { | |
771 remote_ = remote; | |
772 } | |
773 } | |
774 | |
775 bool IsPermissive() const | |
776 { | |
777 return permissive_; | |
778 } | |
779 | |
780 void SetPermissive(bool permissive) | |
781 { | |
782 if (IsStarted()) | |
783 { | |
784 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
785 } | |
786 else | |
787 { | |
788 permissive_ = permissive; | |
789 } | |
790 } | |
791 | |
792 bool HasMoveOriginator() const | |
793 { | |
794 return moveOriginatorId_ != 0; | |
795 } | |
796 | |
797 const std::string& GetMoveOriginatorAet() const | |
798 { | |
799 if (HasMoveOriginator()) | |
800 { | |
801 return moveOriginatorAet_; | |
802 } | |
803 else | |
804 { | |
805 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
806 } | |
807 } | |
808 | |
809 uint16_t GetMoveOriginatorId() const | |
810 { | |
811 if (HasMoveOriginator()) | |
812 { | |
813 return moveOriginatorId_; | |
814 } | |
815 else | |
816 { | |
817 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
818 } | |
819 } | |
820 | |
821 void SetMoveOriginator(const std::string& aet, | |
822 int id) | |
823 { | |
824 if (IsStarted()) | |
825 { | |
826 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
827 } | |
828 else if (id < 0 || | |
829 id >= 65536) | |
830 { | |
831 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
832 } | |
833 else | |
834 { | |
835 moveOriginatorId_ = static_cast<uint16_t>(id); | |
836 moveOriginatorAet_ = aet; | |
837 } | |
838 } | |
839 | |
840 virtual JobStepResult* ExecuteStep() | |
841 { | |
842 if (IsDone()) | |
843 { | |
844 return new JobStepResult(JobStepCode_Success); | |
845 } | |
846 | |
847 Open(); | |
848 | |
849 bool ok = false; | |
850 | |
851 try | |
852 { | |
853 std::string dicom; | |
854 context_.ReadDicom(dicom, GetCurrentInstance()); | |
855 | |
856 if (HasMoveOriginator()) | |
857 { | |
858 connection_->Store(dicom, moveOriginatorAet_, moveOriginatorId_); | |
859 } | |
860 else | |
861 { | |
862 connection_->Store(dicom); | |
863 } | |
864 | |
865 ok = true; | |
866 } | |
867 catch (OrthancException& e) | |
868 { | |
869 } | |
870 | |
871 if (!ok) | |
872 { | |
873 if (permissive_) | |
874 { | |
875 failedInstances_.insert(GetCurrentInstance()); | |
876 } | |
877 else | |
878 { | |
879 return new JobStepResult(JobStepCode_Failure); | |
880 } | |
881 } | |
882 | |
883 Next(); | |
884 | |
885 return new JobStepResult(IsDone() ? JobStepCode_Success : JobStepCode_Continue); | |
886 } | |
887 | |
888 virtual void ReleaseResources() // For pausing jobs | |
889 { | |
890 connection_.release(); | |
891 } | |
892 | |
893 virtual void GetDescription(Json::Value& value) | |
894 { | |
895 value["Type"] = "C-STORE"; | |
896 value["LocalAet"] = localAet_; | |
897 | |
898 Json::Value v; | |
899 remote_.ToJson(v); | |
900 value["Target"] = v; | |
901 | |
902 if (HasMoveOriginator()) | |
903 { | |
904 value["MoveOriginatorAET"] = GetMoveOriginatorAet(); | |
905 value["MoveOriginatorID"] = GetMoveOriginatorId(); | |
906 } | |
907 | |
908 v = Json::arrayValue; | |
909 for (std::set<std::string>::const_iterator it = failedInstances_.begin(); | |
910 it != failedInstances_.end(); ++it) | |
911 { | |
912 v.append(*it); | |
913 } | |
914 | |
915 value["FailedInstances"] = v; | |
916 } | |
917 }; | |
918 } | |
919 | |
920 | |
921 | |
601 TEST(JobsEngine, Basic) | 922 TEST(JobsEngine, Basic) |
602 { | 923 { |
603 JobsEngine engine; | 924 JobsEngine engine; |
604 | 925 |
605 std::string s; | 926 std::string s; |
634 std::cout << v << std::endl; | 955 std::cout << v << std::endl; |
635 } | 956 } |
636 std::cout << "====================================================" << std::endl; | 957 std::cout << "====================================================" << std::endl; |
637 | 958 |
638 boost::this_thread::sleep(boost::posix_time::milliseconds(100)); | 959 boost::this_thread::sleep(boost::posix_time::milliseconds(100)); |
960 | |
961 if (1) | |
962 { | |
963 printf(">> %d\n", engine.GetRegistry().SubmitAndWait(new DummyJob(JobStepResult(Orthanc::JobStepCode_Failure)), rand() % 10)); | |
964 } | |
965 | |
966 boost::this_thread::sleep(boost::posix_time::milliseconds(100)); | |
967 | |
639 | 968 |
640 engine.Stop(); | 969 engine.Stop(); |
641 | 970 |
642 | 971 if (0) |
643 { | 972 { |
644 typedef std::set<std::string> Jobs; | 973 typedef std::set<std::string> Jobs; |
645 | 974 |
646 Jobs jobs; | 975 Jobs jobs; |
647 engine.GetRegistry().ListJobs(jobs); | 976 engine.GetRegistry().ListJobs(jobs); |