Mercurial > hg > orthanc
changeset 2965:9c0b0a6d8b54
MediaArchiveSize configuration option
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 05 Dec 2018 14:33:47 +0100 |
parents | 6896a7c1cbe2 |
children | 10c610e80b15 |
files | OrthancServer/OrthancRestApi/OrthancRestApi.cpp OrthancServer/OrthancRestApi/OrthancRestApi.h OrthancServer/ServerContext.cpp OrthancServer/ServerContext.h OrthancServer/ServerJobs/ArchiveJob.cpp OrthancServer/ServerJobs/ArchiveJob.h Resources/Configuration.json |
diffstat | 7 files changed, 106 insertions(+), 73 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancServer/OrthancRestApi/OrthancRestApi.cpp Wed Dec 05 12:58:56 2018 +0100 +++ b/OrthancServer/OrthancRestApi/OrthancRestApi.cpp Wed Dec 05 14:33:47 2018 +0100 @@ -173,6 +173,78 @@ static const char* KEY_PRIORITY = "Priority"; static const char* KEY_SYNCHRONOUS = "Synchronous"; static const char* KEY_ASYNCHRONOUS = "Asynchronous"; + + + bool OrthancRestApi::IsSynchronousJobRequest(bool isDefaultSynchronous, + const Json::Value& body) const + { + if (body.isMember(KEY_SYNCHRONOUS)) + { + return SerializationToolbox::ReadBoolean(body, KEY_SYNCHRONOUS); + } + else if (body.isMember(KEY_ASYNCHRONOUS)) + { + return !SerializationToolbox::ReadBoolean(body, KEY_ASYNCHRONOUS); + } + else + { + return isDefaultSynchronous; + } + } + + + void OrthancRestApi::SubmitGenericJob(RestApiPostCall& call, + IJob* job, + bool isDefaultSynchronous, + const Json::Value& body) const + { + std::auto_ptr<IJob> raii(job); + + if (job == NULL) + { + throw OrthancException(ErrorCode_NullPointer); + } + + if (body.type() != Json::objectValue) + { + throw OrthancException(ErrorCode_BadFileFormat); + } + + int priority = 0; + + if (body.isMember(KEY_PRIORITY)) + { + priority = SerializationToolbox::ReadInteger(body, KEY_PRIORITY); + } + + if (IsSynchronousJobRequest(isDefaultSynchronous, body)) + { + Json::Value successContent; + if (context_.GetJobsEngine().GetRegistry().SubmitAndWait + (successContent, raii.release(), priority)) + { + // Success in synchronous execution + call.GetOutput().AnswerJson(successContent); + } + else + { + // Error during synchronous execution + call.GetOutput().SignalError(HttpStatus_500_InternalServerError); + } + } + else + { + // Asynchronous mode: Submit the job, but don't wait for its completion + std::string id; + context_.GetJobsEngine().GetRegistry().Submit(id, raii.release(), priority); + + Json::Value v; + v["ID"] = id; + v["Path"] = "/jobs/" + id; + call.GetOutput().AnswerJson(v); + } + } + void OrthancRestApi::SubmitCommandsJob(RestApiPostCall& call, SetOfCommandsJob* job, @@ -202,66 +274,6 @@ job->SetPermissive(false); } - int priority = 0; - - if (body.isMember(KEY_PRIORITY)) - { - priority = SerializationToolbox::ReadInteger(body, KEY_PRIORITY); - } - - bool synchronous = isDefaultSynchronous; - - if (body.isMember(KEY_SYNCHRONOUS)) - { - synchronous = SerializationToolbox::ReadBoolean(body, KEY_SYNCHRONOUS); - } - else if (body.isMember(KEY_ASYNCHRONOUS)) - { - synchronous = !SerializationToolbox::ReadBoolean(body, KEY_ASYNCHRONOUS); - } - - if (synchronous) - { - Json::Value successContent; - if (context_.GetJobsEngine().GetRegistry().SubmitAndWait - (successContent, raii.release(), priority)) - { - // Success in synchronous execution - call.GetOutput().AnswerJson(successContent); - } - else - { - // Error during synchronous execution - call.GetOutput().SignalError(HttpStatus_500_InternalServerError); - } - } - else - { - // Asynchronous mode: Submit the job, but don't wait for its completion - std::string id; - context_.GetJobsEngine().GetRegistry().Submit(id, raii.release(), priority); - - Json::Value v; - v["ID"] = id; - v["Path"] = "/jobs/" + id; - call.GetOutput().AnswerJson(v); - } - } - - - void OrthancRestApi::SubmitCommandsJob(RestApiPostCall& call, - SetOfCommandsJob* job, - bool isDefaultSynchronous) const - { - std::auto_ptr<SetOfCommandsJob> raii(job); - - Json::Value body; - - if (!call.ParseJsonRequest(body)) - { - body = Json::objectValue; - } - - SubmitCommandsJob(call, raii.release(), isDefaultSynchronous, body); + SubmitGenericJob(call, raii.release(), isDefaultSynchronous, body); } }
--- a/OrthancServer/OrthancRestApi/OrthancRestApi.h Wed Dec 05 12:58:56 2018 +0100 +++ b/OrthancServer/OrthancRestApi/OrthancRestApi.h Wed Dec 05 14:33:47 2018 +0100 @@ -103,13 +103,17 @@ ResourceType resourceType, StoreStatus status) const; + bool IsSynchronousJobRequest(bool isDefaultSynchronous, + const Json::Value& body) const; + + void SubmitGenericJob(RestApiPostCall& call, + IJob* job, + bool isDefaultSynchronous, + const Json::Value& body) const; + void SubmitCommandsJob(RestApiPostCall& call, SetOfCommandsJob* job, bool isDefaultSynchronous, const Json::Value& body) const; - - void SubmitCommandsJob(RestApiPostCall& call, - SetOfCommandsJob* job, - bool isDefaultSynchronous) const; }; }
--- a/OrthancServer/ServerContext.cpp Wed Dec 05 12:58:56 2018 +0100 +++ b/OrthancServer/ServerContext.cpp Wed Dec 05 14:33:47 2018 +0100 @@ -235,8 +235,11 @@ { { OrthancConfiguration::ReaderLock lock; + queryRetrieveArchive_.reset( new SharedArchive(lock.GetConfiguration().GetUnsignedIntegerParameter("QueryRetrieveSize", 10))); + mediaArchive_.reset( + new SharedArchive(lock.GetConfiguration().GetUnsignedIntegerParameter("MediaArchiveSize", 1))); defaultLocalAet_ = lock.GetConfiguration().GetStringParameter("DicomAet", "ORTHANC"); jobsEngine_.SetWorkersCount(lock.GetConfiguration().GetUnsignedIntegerParameter("ConcurrentJobs", 2)); }
--- a/OrthancServer/ServerContext.h Wed Dec 05 12:58:56 2018 +0100 +++ b/OrthancServer/ServerContext.h Wed Dec 05 14:33:47 2018 +0100 @@ -189,6 +189,8 @@ std::string defaultLocalAet_; OrthancHttpHandler httpHandler_; + std::auto_ptr<SharedArchive> mediaArchive_; + public: class DicomCacheLocker : public boost::noncopyable { @@ -310,6 +312,11 @@ return *queryRetrieveArchive_; } + SharedArchive& GetMediaArchive() + { + return *mediaArchive_; + } + const std::string& GetDefaultLocalApplicationEntityTitle() const { return defaultLocalAet_;
--- a/OrthancServer/ServerJobs/ArchiveJob.cpp Wed Dec 05 12:58:56 2018 +0100 +++ b/OrthancServer/ServerJobs/ArchiveJob.cpp Wed Dec 05 14:33:47 2018 +0100 @@ -778,11 +778,11 @@ }; - ArchiveJob::ArchiveJob(boost::shared_ptr<TemporaryFile>& target, + ArchiveJob::ArchiveJob(boost::shared_ptr<TemporaryFile>& synchronousTarget, ServerContext& context, bool isMedia, bool enableExtendedSopClass) : - target_(target), + synchronousTarget_(synchronousTarget), context_(context), archive_(new ArchiveIndex(ResourceType_Patient)), // root isMedia_(isMedia), @@ -791,7 +791,7 @@ instancesCount_(0), uncompressedSize_(0) { - if (target.get() == NULL) + if (synchronousTarget.get() == NULL) { throw OrthancException(ErrorCode_NullPointer); } @@ -824,7 +824,7 @@ throw OrthancException(ErrorCode_BadSequenceOfCalls); } - writer_.reset(new ZipWriterIterator(*target_, context_, *archive_, + writer_.reset(new ZipWriterIterator(*synchronousTarget_, context_, *archive_, isMedia_, enableExtendedSopClass_)); instancesCount_ = writer_->GetInstancesCount(); @@ -836,7 +836,7 @@ { assert(writer_.get() != NULL); - if (target_.unique()) + if (synchronousTarget_.unique()) { LOG(WARNING) << "A client has disconnected while creating an archive"; return JobStepResult::Failure(ErrorCode_NetworkProtocol);
--- a/OrthancServer/ServerJobs/ArchiveJob.h Wed Dec 05 12:58:56 2018 +0100 +++ b/OrthancServer/ServerJobs/ArchiveJob.h Wed Dec 05 14:33:47 2018 +0100 @@ -50,7 +50,7 @@ class ZipCommands; class ZipWriterIterator; - boost::shared_ptr<TemporaryFile> target_; + boost::shared_ptr<TemporaryFile> synchronousTarget_; ServerContext& context_; boost::shared_ptr<ArchiveIndex> archive_; bool isMedia_; @@ -63,7 +63,7 @@ uint64_t uncompressedSize_; public: - ArchiveJob(boost::shared_ptr<TemporaryFile>& target, + ArchiveJob(boost::shared_ptr<TemporaryFile>& synchronousTarget, ServerContext& context, bool isMedia, bool enableExtendedSopClass);
--- a/Resources/Configuration.json Wed Dec 05 12:58:56 2018 +0100 +++ b/Resources/Configuration.json Wed Dec 05 14:33:47 2018 +0100 @@ -440,5 +440,12 @@ // instance replaces the old one. If set to "false", the new // instance is discarded and the old one is kept. Up to Orthanc // 1.4.1, the implicit behavior corresponded to "false". - "OverwriteInstances" : false + "OverwriteInstances" : false, + + // Maximum number of ZIP/media archives that are maintained by + // Orthanc, as a response to the asynchronous creation of archives. + // The least recently used archives get deleted as new archives are + // generated. This option was introduced in Orthanc 1.4.3, and has + // no effect on the synchronous generation of archives. + "MediaArchiveSize" : 1 }