Selaa lähdekoodia

Merge pull request #6040 from jakesmith/hpcc-11261-for-4.2.6

HPCC-11261 - fileservice superfile actions can lockup on retry

Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 11 vuotta sitten
vanhempi
commit
413b335f03
1 muutettua tiedostoa jossa 43 lisäystä ja 4 poistoa
  1. 43 4
      plugins/fileservices/fileservices.cpp

+ 43 - 4
plugins/fileservices/fileservices.cpp

@@ -1156,6 +1156,27 @@ FILESERVICES_API void FILESERVICES_CALL fsAddSuperFile(IGlobalCodeContext *gctx,
 }
 
 
+class CImplicitSuperTransaction
+{
+    IDistributedFileTransaction *transaction;
+public:
+    CImplicitSuperTransaction(IDistributedFileTransaction *_transaction)
+    {
+        if (!_transaction->active()) // then created implicitly
+        {
+            transaction = _transaction;
+            transaction->start();
+        }
+        else
+            transaction = NULL;
+    }
+    ~CImplicitSuperTransaction()
+    {
+        if (transaction)
+            transaction->commit();
+    }
+};
+
 FILESERVICES_API void FILESERVICES_CALL fslAddSuperFile(ICodeContext *ctx, const char *lsuperfn,const char *_lfn,unsigned atpos,bool addcontents, bool strict)
 {
     Owned<IDistributedSuperFile> file;
@@ -1185,7 +1206,11 @@ FILESERVICES_API void FILESERVICES_CALL fslAddSuperFile(ICodeContext *ctx, const
     StringBuffer other;
     if (atpos>1)
         other.append("#").append(atpos);
-    file->addSubFile(lfn.str(),atpos>0,(atpos>1)?other.str():NULL,addcontents,transaction);
+    {
+        CImplicitSuperTransaction implicitTransaction(transaction);
+        file->addSubFile(lfn.str(),atpos>0,(atpos>1)?other.str():NULL,addcontents,transaction);
+        file.clear(); // Must clear file before implicit transaction executed in destructor
+    }
     StringBuffer s("AddSuperFile ('");
     s.append(lsfn).append("', '");
     s.append(lfn).append('\'');
@@ -1217,7 +1242,11 @@ FILESERVICES_API void FILESERVICES_CALL fslRemoveSuperFile(ICodeContext *ctx, co
     lookupSuperFile(ctx, lsuperfn, file, true, lsfn, false, true);
     IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
     assertex(transaction);
-    file->removeSubFile(_lfn?lfn.str():NULL,del,remcontents,transaction);
+    {
+        CImplicitSuperTransaction implicitTransaction(transaction);
+        file->removeSubFile(_lfn?lfn.str():NULL,del,remcontents,transaction);
+        file.clear(); // Must clear file before implicit transaction executed in destructor
+    }
     StringBuffer s;
     if (_lfn)
         s.append("RemoveSuperFile ('");
@@ -1261,7 +1290,11 @@ FILESERVICES_API void FILESERVICES_CALL fslRemoveOwnedSubFiles(ICodeContext *ctx
     lookupSuperFile(ctx, lsuperfn, file, true, lsfn, false, true);
     IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
     assertex(transaction);
-    file->removeOwnedSubFiles(del,transaction);
+    {
+        CImplicitSuperTransaction implicitTransaction(transaction);
+        file->removeOwnedSubFiles(del,transaction);
+        file.clear(); // Must clear file before implicit transaction executed in destructor
+    }
     VStringBuffer s("RemoveOwnedSubFiles ('%s'", lsfn.str());
     if (del)
         s.append(", del");
@@ -1295,7 +1328,13 @@ FILESERVICES_API void FILESERVICES_CALL fslSwapSuperFile(ICodeContext *ctx, cons
 
     IDistributedFileTransaction *transaction = ctx->querySuperFileTransaction();
     assertex(transaction);
-    file1->swapSuperFile(file2,transaction);
+    {
+        CImplicitSuperTransaction implicitTransaction(transaction);
+        file1->swapSuperFile(file2,transaction);
+        // Must clear files before implicit transaction executed in destructor
+        file1.clear();
+        file2.clear();
+    }
     StringBuffer s("SwapSuperFile ('");
     s.append(lsfn1).append("', '");
     s.append(lsfn2).append("') '");