changeset 2624:714dcddeb65f jobs

asynchronous c-movoe
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 24 May 2018 21:44:22 +0200
parents bd6e0b70e915
children 5469dda691cd
files Core/JobsEngine/SetOfInstancesJob.cpp Core/JobsEngine/SetOfInstancesJob.h OrthancServer/OrthancMoveRequestHandler.cpp OrthancServer/OrthancRestApi/OrthancRestModalities.cpp OrthancServer/ServerJobs/DicomModalityStoreJob.cpp OrthancServer/ServerJobs/LuaJobManager.cpp OrthancServer/ServerJobs/OrthancPeerStoreJob.cpp
diffstat 7 files changed, 123 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/Core/JobsEngine/SetOfInstancesJob.cpp	Wed May 23 14:28:25 2018 +0200
+++ b/Core/JobsEngine/SetOfInstancesJob.cpp	Thu May 24 21:44:22 2018 +0200
@@ -188,7 +188,6 @@
     }
 
     value["Instances"] = v;
-
       
     v = Json::arrayValue;
 
--- a/Core/JobsEngine/SetOfInstancesJob.h	Wed May 23 14:28:25 2018 +0200
+++ b/Core/JobsEngine/SetOfInstancesJob.h	Thu May 24 21:44:22 2018 +0200
@@ -47,6 +47,7 @@
     bool                      permissive_;
     size_t                    position_;
     std::set<std::string>     failedInstances_;
+    std::string               description_;
 
   protected:
     virtual bool HandleInstance(const std::string& instance) = 0;
@@ -54,6 +55,16 @@
   public:
     SetOfInstancesJob();
 
+    void SetDescription(const std::string& description)
+    {
+      description_ = description;
+    }
+
+    const std::string& GetDescription() const
+    {
+      return description_;
+    }
+
     void Reserve(size_t size);
 
     size_t GetInstancesCount() const
--- a/OrthancServer/OrthancMoveRequestHandler.cpp	Wed May 23 14:28:25 2018 +0200
+++ b/OrthancServer/OrthancMoveRequestHandler.cpp	Thu May 24 21:44:22 2018 +0200
@@ -38,6 +38,7 @@
 #include "../../Core/DicomParsing/FromDcmtkBridge.h"
 #include "../Core/DicomFormat/DicomArray.h"
 #include "../Core/Logging.h"
+#include "ServerJobs/DicomModalityStoreJob.h"
 
 namespace Orthanc
 {
@@ -45,7 +46,7 @@
   {
     // Anonymous namespace to avoid clashes between compilation modules
 
-    class OrthancMoveRequestIterator : public IMoveRequestIterator
+    class SynchronousMove : public IMoveRequestIterator
     {
     private:
       ServerContext& context_;
@@ -58,11 +59,11 @@
       std::auto_ptr<DicomUserConnection> connection_;
 
     public:
-      OrthancMoveRequestIterator(ServerContext& context,
-                                 const std::string& aet,
-                                 const std::string& publicId,
-                                 const std::string& originatorAet,
-                                 uint16_t originatorId) :
+      SynchronousMove(ServerContext& context,
+                      const std::string& aet,
+                      const std::string& publicId,
+                      const std::string& originatorAet,
+                      uint16_t originatorId) :
         context_(context),
         localAet_(context.GetDefaultLocalApplicationEntityTitle()),
         position_(0),
@@ -110,6 +111,66 @@
         return Status_Success;
       }
     };
+
+
+    class AsynchronousMove : public IMoveRequestIterator
+    {
+    private:
+      ServerContext&                        context_;
+      std::auto_ptr<DicomModalityStoreJob>  job_;
+      size_t                                position_;
+      
+    public:
+      AsynchronousMove(ServerContext& context,
+                       const std::string& aet,
+                       const std::string& publicId,
+                       const std::string& originatorAet,
+                       uint16_t originatorId) :
+        context_(context),
+        job_(new DicomModalityStoreJob(context)),
+        position_(0)
+      {
+        LOG(INFO) << "Sending resource " << publicId << " to modality \"" << aet << "\"";
+
+        job_->SetDescription("C-MOVE");
+        job_->SetPermissive(true);
+        job_->SetLocalAet(context.GetDefaultLocalApplicationEntityTitle());
+        job_->SetRemoteModality(Configuration::GetModalityUsingAet(aet));
+
+        if (originatorId != 0)
+        {
+          job_->SetMoveOriginator(originatorAet, originatorId);
+        }
+        
+        std::list<std::string> tmp;
+        context_.GetIndex().GetChildInstances(tmp, publicId);
+
+        job_->Reserve(tmp.size());
+
+        for (std::list<std::string>::iterator it = tmp.begin(); it != tmp.end(); ++it)
+        {
+          job_->AddInstance(*it);
+        }
+      }
+
+      virtual unsigned int GetSubOperationCount() const
+      {
+        return 1;
+      }
+
+      virtual Status DoNext()
+      {
+        if (position_ == 0)
+        {
+          context_.GetJobsEngine().GetRegistry().Submit(job_.release(), 0 /* priority */);
+          return Status_Success;
+        }
+        else
+        {
+          return Status_Failure;
+        }
+      }
+    };
   }
 
 
@@ -217,7 +278,8 @@
           LookupIdentifier(publicId, ResourceType_Study, input) ||
           LookupIdentifier(publicId, ResourceType_Patient, input))
       {
-        return new OrthancMoveRequestIterator(context_, targetAet, publicId, originatorAet, originatorId);
+        return new AsynchronousMove(context_, targetAet, publicId, originatorAet, originatorId);
+        //return new SynchronousMove(context_, targetAet, publicId, originatorAet, originatorId);
       }
       else
       {
@@ -238,7 +300,8 @@
 
     if (LookupIdentifier(publicId, level, input))
     {
-      return new OrthancMoveRequestIterator(context_, targetAet, publicId, originatorAet, originatorId);
+      return new AsynchronousMove(context_, targetAet, publicId, originatorAet, originatorId);
+      //return new SynchronousMove(context_, targetAet, publicId, originatorAet, originatorId);
     }
     else
     {
--- a/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp	Wed May 23 14:28:25 2018 +0200
+++ b/OrthancServer/OrthancRestApi/OrthancRestModalities.cpp	Thu May 24 21:44:22 2018 +0200
@@ -710,7 +710,7 @@
     
     ServerContext& context = OrthancRestApi::GetContext(call);
 
-    bool permissive = Toolbox::GetJsonBooleanField(request, "Permissive", false);
+    bool permissive = Toolbox::GetJsonBooleanField(request, "Permissive", true);
     bool asynchronous = Toolbox::GetJsonBooleanField(request, "Asynchronous", false);
     int priority = Toolbox::GetJsonIntegerField(request, "Priority", 0);
 
@@ -768,6 +768,7 @@
     RemoteModalityParameters p = Configuration::GetModalityUsingSymbolicName(remote);
 
     std::auto_ptr<DicomModalityStoreJob> job(new DicomModalityStoreJob(context));
+    job->SetDescription("REST API");
     job->SetLocalAet(localAet);
     job->SetRemoteModality(p);
 
@@ -907,6 +908,7 @@
     Configuration::GetOrthancPeer(peer, remote);
 
     std::auto_ptr<OrthancPeerStoreJob> job(new OrthancPeerStoreJob(context));
+    job->SetDescription("REST API");
     job->SetPeer(peer);    
 
     SubmitJob(call, request, instances, job.release());
--- a/OrthancServer/ServerJobs/DicomModalityStoreJob.cpp	Wed May 23 14:28:25 2018 +0200
+++ b/OrthancServer/ServerJobs/DicomModalityStoreJob.cpp	Thu May 24 21:44:22 2018 +0200
@@ -57,7 +57,16 @@
               << remote_.GetApplicationEntityTitle() << "\"";
 
     std::string dicom;
-    context_.ReadDicom(dicom, instance);
+
+    try
+    {
+      context_.ReadDicom(dicom, instance);
+    }
+    catch (OrthancException& e)
+    {
+      LOG(WARNING) << "An instance was removed after the job was issued: " << instance;
+      return false;
+    }
 
     if (HasMoveOriginator())
     {
@@ -161,6 +170,7 @@
 
   void DicomModalityStoreJob::GetPublicContent(Json::Value& value)
   {
+    value["Description"] = GetDescription();
     value["LocalAet"] = localAet_;
     value["RemoteAet"] = remote_.GetApplicationEntityTitle();
 
--- a/OrthancServer/ServerJobs/LuaJobManager.cpp	Wed May 23 14:28:25 2018 +0200
+++ b/OrthancServer/ServerJobs/LuaJobManager.cpp	Thu May 24 21:44:22 2018 +0200
@@ -154,12 +154,27 @@
 
   LuaJobManager::Lock::~Lock()
   {
+    bool isEmpty;
+    
     assert(jobLock_.get() != NULL);
+    isEmpty = (isNewJob_ &&
+               jobLock_->GetOperationsCount() == 0);
+    
     jobLock_.reset(NULL);
 
     if (isNewJob_)
     {
-      engine_.GetRegistry().Submit(that_.currentId_, that_.currentJob_, that_.priority_);
+      if (isEmpty)
+      {
+        // No operation was added, discard the newly created job
+        isNewJob_ = false;
+        delete that_.currentJob_;
+        that_.currentJob_ = NULL;
+      }
+      else
+      {
+        engine_.GetRegistry().Submit(that_.currentId_, that_.currentJob_, that_.priority_);
+      }
     }
   }
 
--- a/OrthancServer/ServerJobs/OrthancPeerStoreJob.cpp	Wed May 23 14:28:25 2018 +0200
+++ b/OrthancServer/ServerJobs/OrthancPeerStoreJob.cpp	Thu May 24 21:44:22 2018 +0200
@@ -52,7 +52,15 @@
     LOG(INFO) << "Sending instance " << instance << " to peer \"" 
               << peer_.GetUrl() << "\"";
 
-    context_.ReadDicom(client_->GetBody(), instance);
+    try
+    {
+      context_.ReadDicom(client_->GetBody(), instance);
+    }
+    catch (OrthancException& e)
+    {
+      LOG(WARNING) << "An instance was removed after the job was issued: " << instance;
+      return false;
+    }
 
     std::string answer;
     if (client_->Apply(answer))
@@ -90,7 +98,8 @@
     Json::Value v;
     peer_.ToJson(v);
     value["Peer"] = v;
-        
+
+    value["Description"] = GetDescription();
     value["InstancesCount"] = static_cast<uint32_t>(GetInstances().size());
     value["FailedInstancesCount"] = static_cast<uint32_t>(GetFailedInstances().size());
   }