diff OrthancServer/Sources/ServerIndex.cpp @ 4551:350a22c094f2 db-changes

testing replay of transactions
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 02 Mar 2021 19:36:59 +0100
parents 5b929e6b3c36
children efd90f778cd2
line wrap: on
line diff
--- a/OrthancServer/Sources/ServerIndex.cpp	Tue Mar 02 16:51:19 2021 +0100
+++ b/OrthancServer/Sources/ServerIndex.cpp	Tue Mar 02 19:36:59 2021 +0100
@@ -679,7 +679,8 @@
     db_(db),
     maximumStorageSize_(0),
     maximumPatients_(0),
-    mainDicomTagsRegistry_(new MainDicomTagsRegistry)
+    mainDicomTagsRegistry_(new MainDicomTagsRegistry),
+    maxRetries_(0)
   {
     listener_.reset(new Listener(context));
     db_.SetListener(*listener_);
@@ -2622,4 +2623,163 @@
       CopyListToVector(*instancesId, instancesList);
     }
   }
+
+
+
+
+
+  /***
+   ** PROTOTYPING FOR DB REFACTORING BELOW
+   ***/
+    
+  ServerIndex::ExpandResourceOperation::ExpandResourceOperation(const std::string& resource,
+                                                                ResourceType level) :
+    found_(false),
+    resource_(resource),
+    level_(level)
+  {
+  }
+
+  
+  void ServerIndex::ExpandResourceOperation::Apply(ServerIndex::ReadOnlyTransaction& transaction)
+  {
+    found_ = transaction.LookupResource(item_, resource_, level_);
+  }
+
+  
+  const Json::Value& ServerIndex::ExpandResourceOperation::GetResource() const
+  {
+    if (found_)
+    {
+      return item_;
+    }
+    else
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+  }
+
+
+  class ServerIndex::ReadOnlyWrapper : public IReadOnlyOperations
+  {
+  private:
+    ReadOnlyFunction  func_;
+
+  public:
+    ReadOnlyWrapper(ReadOnlyFunction  func) :
+      func_(func)
+    {
+      assert(func_ != NULL);
+    }
+
+    virtual void Apply(ReadOnlyTransaction& transaction)
+    {
+      func_(transaction);
+    }
+  };
+
+  
+  class ServerIndex::ReadWriteWrapper : public IReadWriteOperations
+  {
+  private:
+    ReadWriteFunction  func_;
+
+  public:
+    ReadWriteWrapper(ReadWriteFunction  func) :
+      func_(func)
+    {
+      assert(func_ != NULL);
+    }
+
+    virtual void Apply(ReadWriteTransaction& transaction)
+    {
+      func_(transaction);
+    }
+  };
+
+
+  void ServerIndex::ApplyInternal(IReadOnlyOperations* readOperations,
+                                  IReadWriteOperations* writeOperations)
+  {
+    if ((readOperations == NULL && writeOperations == NULL) ||
+        (readOperations != NULL && writeOperations != NULL))
+    {
+      throw OrthancException(ErrorCode_InternalError);
+    }
+    
+    unsigned int count = 0;
+
+    for (;;)
+    {
+      try
+      {
+        if (readOperations != NULL)
+        {
+          ReadOnlyTransaction transaction(*this);
+          readOperations->Apply(transaction);
+        }
+        else
+        {
+          assert(writeOperations != NULL);
+          ReadWriteTransaction transaction(*this);
+          writeOperations->Apply(transaction);          
+        }
+        
+        return;  // Success
+      }
+      catch (OrthancException& e)
+      {
+        if (e.GetErrorCode() == ErrorCode_DatabaseCannotSerialize)
+        {
+          if (count == maxRetries_)
+          {
+            throw;
+          }
+          else
+          {
+            count++;
+            boost::this_thread::sleep(boost::posix_time::milliseconds(100 * count));
+          }          
+        }
+        else if (e.GetErrorCode() == ErrorCode_DatabaseUnavailable)
+        {
+          if (count == maxRetries_)
+          {
+            throw;
+          }
+          else
+          {
+            count++;
+            boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
+          }
+        }
+        else
+        {
+          throw;
+        }
+      }
+    }
+  }
+  
+  void ServerIndex::Apply(IReadOnlyOperations& operations)
+  {
+    ApplyInternal(&operations, NULL);
+  }
+  
+  void ServerIndex::Apply(IReadWriteOperations& operations)
+  {
+    ApplyInternal(NULL, &operations);
+  }
+  
+  void ServerIndex::Apply(ReadOnlyFunction func)
+  {
+    ReadOnlyWrapper wrapper(func);
+    Apply(wrapper);
+  }
+  
+  void ServerIndex::Apply(ReadWriteFunction func)
+  {
+    ReadWriteWrapper wrapper(func);
+    Apply(wrapper);
+  }
 }