|
@@ -38,6 +38,7 @@
|
|
|
#include "mputil.hpp"
|
|
|
#include "rmtfile.hpp"
|
|
|
#include "dadfs.hpp"
|
|
|
+#include "eclhelper.hpp"
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
//#define EXTRA_LOGGING
|
|
@@ -964,6 +965,7 @@ interface IDistributedFileTransactionExt : extends IDistributedFileTransaction
|
|
|
virtual void retryActions()=0;
|
|
|
virtual void runActions()=0;
|
|
|
virtual void commitAndClearup()=0;
|
|
|
+ virtual ICodeContext *queryCodeContext()=0;
|
|
|
};
|
|
|
|
|
|
class CDistributedFileDirectory: public CInterface, implements IDistributedFileDirectory
|
|
@@ -1324,7 +1326,7 @@ public:
|
|
|
// This will do the right thing for either super-files and logical-files.
|
|
|
try
|
|
|
{
|
|
|
- file->detach(0); // 0 == timeout immediately if cannot get exclusive lock
|
|
|
+ file->detach(0, NULL); // 0 == timeout immediately if cannot get exclusive lock
|
|
|
return;
|
|
|
}
|
|
|
catch (ISDSException *e)
|
|
@@ -1458,6 +1460,7 @@ class CDistributedFileTransaction: public CInterface, implements IDistributedFil
|
|
|
// any exception to the rule used by addSubFile / removeSubFile
|
|
|
unsigned depth;
|
|
|
unsigned prepared;
|
|
|
+ ICodeContext *codeCtx;
|
|
|
|
|
|
/* 'owner' is set if, transaction object is implicitly created, because none provided
|
|
|
* The owner cannot be release or unlocked. The transaction can still retry if other files are locked,
|
|
@@ -1465,8 +1468,6 @@ class CDistributedFileTransaction: public CInterface, implements IDistributedFil
|
|
|
*/
|
|
|
IDistributedSuperFile *owner;
|
|
|
|
|
|
-
|
|
|
- void validateAddSubFile(IDistributedSuperFile *super, IDistributedFile *sub, const char *subName);
|
|
|
CTransactionFile *queryCreate(const char *name, IDistributedFile *file, bool recreate=false)
|
|
|
{
|
|
|
Owned<CTransactionFile> trackedFile;
|
|
@@ -1486,11 +1487,42 @@ class CDistributedFileTransaction: public CInterface, implements IDistributedFil
|
|
|
{
|
|
|
return trackedFiles.find(file);
|
|
|
}
|
|
|
-
|
|
|
+ void commitActions()
|
|
|
+ {
|
|
|
+ while (actions.ordinality()) // if we get here everything should work!
|
|
|
+ {
|
|
|
+ Owned<CDFAction> action = &actions.popGet();
|
|
|
+ action->commit();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ IDistributedFile *findFile(const char *name)
|
|
|
+ {
|
|
|
+ StringBuffer tmp;
|
|
|
+ name = normalizeLFN(name, tmp);
|
|
|
+ CTransactionFile *trackedFile = trackedFilesByName.find(tmp.str());
|
|
|
+ if (!trackedFile)
|
|
|
+ return NULL;
|
|
|
+ return trackedFile->queryFile();
|
|
|
+ }
|
|
|
+ void deleteFiles() // no rollback at this point
|
|
|
+ {
|
|
|
+ Owned<IMultiException> me = MakeMultiException("Transaction");
|
|
|
+ ForEachItemIn(i,delayeddelete) {
|
|
|
+ try {
|
|
|
+ delayeddelete.item(i).doDelete();
|
|
|
+ } catch (IException *e) {
|
|
|
+ me->append(*e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ delayeddelete.kill();
|
|
|
+ if (me->ordinality())
|
|
|
+ throw me.getClear();
|
|
|
+ }
|
|
|
public:
|
|
|
IMPLEMENT_IINTERFACE;
|
|
|
- CDistributedFileTransaction(IUserDescriptor *user, IDistributedSuperFile *_owner=NULL)
|
|
|
- : isactive(false), depth(0), prepared(0), owner(_owner)
|
|
|
+
|
|
|
+ CDistributedFileTransaction(IUserDescriptor *user, IDistributedSuperFile *_owner=NULL, ICodeContext *_codeCtx=NULL)
|
|
|
+ : isactive(false), depth(0), prepared(0), owner(_owner), codeCtx(_codeCtx)
|
|
|
{
|
|
|
setUserDescriptor(udesc,user);
|
|
|
}
|
|
@@ -1502,79 +1534,8 @@ public:
|
|
|
rollback();
|
|
|
assert(depth == 0);
|
|
|
}
|
|
|
- void ensureFile(IDistributedFile *file)
|
|
|
- {
|
|
|
- if (!trackedFiles.find(file))
|
|
|
- addFile(file);
|
|
|
- }
|
|
|
- void addFile(IDistributedFile *file)
|
|
|
- {
|
|
|
- CTransactionFile *trackedFile = queryCreate(file->queryLogicalName(), file, false);
|
|
|
- // Also add subfiles to cache
|
|
|
- IDistributedSuperFile *sfile = file->querySuperFile();
|
|
|
- if (sfile)
|
|
|
- {
|
|
|
- Owned<IDistributedFileIterator> iter = sfile->getSubFileIterator();
|
|
|
- ForEach(*iter)
|
|
|
- {
|
|
|
- IDistributedFile *f = &iter->query();
|
|
|
- trackedFile->noteAddSubFile(f);
|
|
|
- addFile(f);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- void noteAddSubFile(IDistributedSuperFile *super, const char *superName, IDistributedFile *sub)
|
|
|
- {
|
|
|
- CTransactionFile *trackedSuper = queryCreate(superName, super);
|
|
|
- trackedSuper->noteAddSubFile(sub);
|
|
|
- }
|
|
|
- void noteRemoveSubFile(IDistributedSuperFile *super, IDistributedFile *sub)
|
|
|
- {
|
|
|
- CTransactionFile *trackedSuper = lookupTrackedFile(super);
|
|
|
- if (trackedSuper)
|
|
|
- trackedSuper->noteRemoveSubFile(sub);
|
|
|
- }
|
|
|
- virtual void clearSubFiles(IDistributedSuperFile *super)
|
|
|
- {
|
|
|
- CTransactionFile *trackedSuper = lookupTrackedFile(super);
|
|
|
- if (trackedSuper)
|
|
|
- trackedSuper->clearSubs();
|
|
|
- }
|
|
|
- virtual void noteSuperSwap(IDistributedSuperFile *super1, IDistributedSuperFile *super2)
|
|
|
- {
|
|
|
- CTransactionFile *trackedSuper1 = lookupTrackedFile(super1);
|
|
|
- CTransactionFile *trackedSuper2 = lookupTrackedFile(super2);
|
|
|
- assertex(trackedSuper1 && trackedSuper2);
|
|
|
- ICopyArrayOf<IDistributedFile> super1Subs, super2Subs;
|
|
|
- Owned<IDistributedFileIterator> iter = trackedSuper1->getSubFiles();
|
|
|
- ForEach(*iter)
|
|
|
- super1Subs.append(iter->query());
|
|
|
- trackedSuper1->clearSubs();
|
|
|
- iter.setown(trackedSuper2->getSubFiles());
|
|
|
- ForEach(*iter)
|
|
|
- super2Subs.append(iter->query());
|
|
|
- trackedSuper2->clearSubs();
|
|
|
- ForEachItemIn(s, super2Subs)
|
|
|
- trackedSuper1->noteAddSubFile(&super2Subs.item(s));
|
|
|
- ForEachItemIn(s2, super1Subs)
|
|
|
- trackedSuper2->noteAddSubFile(&super1Subs.item(s2));
|
|
|
- }
|
|
|
- void noteRename(IDistributedFile *file, const char *newName)
|
|
|
- {
|
|
|
- CTransactionFile *trackedFile = lookupTrackedFile(file);
|
|
|
- if (trackedFile)
|
|
|
- {
|
|
|
- trackedFiles.removeExact(trackedFile);
|
|
|
- trackedFilesByName.removeExact(trackedFile);
|
|
|
- trackedFile = queryCreate(newName, file);
|
|
|
- }
|
|
|
- }
|
|
|
- void addAction(CDFAction *action)
|
|
|
- {
|
|
|
- actions.append(*action); // takes ownership
|
|
|
- action->setTransaction(this);
|
|
|
- }
|
|
|
- void start()
|
|
|
+// IDistributedFileTransaction impl.
|
|
|
+ virtual void start()
|
|
|
{
|
|
|
if (isactive)
|
|
|
throw MakeStringException(-1,"Transaction already started");
|
|
@@ -1584,39 +1545,7 @@ public:
|
|
|
prepared = 0;
|
|
|
assertex(actions.ordinality()==0);
|
|
|
}
|
|
|
- bool prepareActions()
|
|
|
- {
|
|
|
- prepared = 0;
|
|
|
- unsigned toPrepare = actions.ordinality();
|
|
|
- ForEachItemIn(i0,actions)
|
|
|
- {
|
|
|
- if (actions.item(i0).prepare())
|
|
|
- ++prepared;
|
|
|
- else
|
|
|
- break;
|
|
|
- }
|
|
|
- return prepared == toPrepare;
|
|
|
- }
|
|
|
- void retryActions()
|
|
|
- {
|
|
|
- clearFiles(); // clear all previously tracked pending file changes, e.g. renames, super file additions/removals
|
|
|
- while (prepared) // unlock for retry
|
|
|
- actions.item(--prepared).retry();
|
|
|
- }
|
|
|
- void runActions()
|
|
|
- {
|
|
|
- ForEachItemIn(i,actions)
|
|
|
- actions.item(i).run();
|
|
|
- }
|
|
|
- void commitActions()
|
|
|
- {
|
|
|
- while (actions.ordinality()) // if we get here everything should work!
|
|
|
- {
|
|
|
- Owned<CDFAction> action = &actions.popGet();
|
|
|
- action->commit();
|
|
|
- }
|
|
|
- }
|
|
|
- void commit()
|
|
|
+ virtual void commit()
|
|
|
{
|
|
|
if (!isactive)
|
|
|
return;
|
|
@@ -1644,17 +1573,7 @@ public:
|
|
|
rollback();
|
|
|
throw rete;
|
|
|
}
|
|
|
- void commitAndClearup()
|
|
|
- {
|
|
|
- // =============== COMMIT and CLEANUP
|
|
|
- commitActions();
|
|
|
- clearFiles();
|
|
|
- isactive = false;
|
|
|
- actions.kill();
|
|
|
- deleteFiles();
|
|
|
- }
|
|
|
-
|
|
|
- void rollback()
|
|
|
+ virtual void rollback()
|
|
|
{
|
|
|
// =============== ROLLBACK AND CLEANUP
|
|
|
while (actions.ordinality())
|
|
@@ -1681,46 +1600,11 @@ public:
|
|
|
// this we only want to do if active
|
|
|
delayeddelete.kill();
|
|
|
}
|
|
|
-
|
|
|
- void autoCommit()
|
|
|
- {
|
|
|
- // Recursive calls to transaction will not commit until
|
|
|
- // all calls have finished (gone back to zero depth)
|
|
|
- if (!depth && !isactive) {
|
|
|
- try {
|
|
|
- isactive = true;
|
|
|
- commit();
|
|
|
- }
|
|
|
- catch (IException *) {
|
|
|
- rollback();
|
|
|
- throw;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Call this when you're recurring
|
|
|
- void descend()
|
|
|
- {
|
|
|
- depth++;
|
|
|
- }
|
|
|
-
|
|
|
- // Call this at the end of the block that started recursion
|
|
|
- void ascend()
|
|
|
- {
|
|
|
- assertex(depth);
|
|
|
- depth--;
|
|
|
- }
|
|
|
-
|
|
|
- IDistributedFile *findFile(const char *name)
|
|
|
+ virtual bool active()
|
|
|
{
|
|
|
- StringBuffer tmp;
|
|
|
- name = normalizeLFN(name, tmp);
|
|
|
- CTransactionFile *trackedFile = trackedFilesByName.find(tmp.str());
|
|
|
- if (!trackedFile)
|
|
|
- return NULL;
|
|
|
- return trackedFile->queryFile();
|
|
|
+ return isactive;
|
|
|
}
|
|
|
- IDistributedFile *lookupFile(const char *name,unsigned timeout)
|
|
|
+ virtual IDistributedFile *lookupFile(const char *name,unsigned timeout)
|
|
|
{
|
|
|
IDistributedFile *ret = findFile(name);
|
|
|
if (ret)
|
|
@@ -1733,8 +1617,7 @@ public:
|
|
|
return ret;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- IDistributedSuperFile *lookupSuperFile(const char *name, unsigned timeout)
|
|
|
+ virtual IDistributedSuperFile *lookupSuperFile(const char *name, unsigned timeout)
|
|
|
{
|
|
|
IDistributedFile *f = findFile(name);
|
|
|
if (f)
|
|
@@ -1747,29 +1630,62 @@ public:
|
|
|
return ret;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- virtual bool isSubFile(IDistributedSuperFile *super, const char *subFile, bool sub)
|
|
|
+// IDistributedFileTransactionExt impl.
|
|
|
+ virtual IUserDescriptor *queryUser()
|
|
|
{
|
|
|
- CTransactionFile *trackedSuper = lookupTrackedFile(super);
|
|
|
- if (!trackedSuper)
|
|
|
- return false;
|
|
|
- return trackedSuper->find(subFile, sub);
|
|
|
+ return udesc;
|
|
|
}
|
|
|
-
|
|
|
-public:
|
|
|
- bool active()
|
|
|
+ virtual void descend() // Call this when you're recurring
|
|
|
{
|
|
|
- return isactive;
|
|
|
+ depth++;
|
|
|
}
|
|
|
-
|
|
|
- void clearFiles()
|
|
|
+ virtual void ascend() // Call this at the end of the block that started recursion
|
|
|
{
|
|
|
- trackedFiles.kill();
|
|
|
- trackedFilesByName.kill();
|
|
|
- if (owner)
|
|
|
- addFile(owner); // ensure remains tracked
|
|
|
+ assertex(depth);
|
|
|
+ depth--;
|
|
|
+ }
|
|
|
+ virtual void autoCommit()
|
|
|
+ {
|
|
|
+ // Recursive calls to transaction will not commit until
|
|
|
+ // all calls have finished (gone back to zero depth)
|
|
|
+ if (!depth && !isactive) {
|
|
|
+ try {
|
|
|
+ isactive = true;
|
|
|
+ commit();
|
|
|
+ }
|
|
|
+ catch (IException *) {
|
|
|
+ rollback();
|
|
|
+ throw;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- void clearFile(IDistributedFile *file)
|
|
|
+ virtual void addAction(CDFAction *action)
|
|
|
+ {
|
|
|
+ actions.append(*action); // takes ownership
|
|
|
+ action->setTransaction(this);
|
|
|
+ }
|
|
|
+ virtual void addFile(IDistributedFile *file)
|
|
|
+ {
|
|
|
+ CTransactionFile *trackedFile = queryCreate(file->queryLogicalName(), file, false);
|
|
|
+ // Also add subfiles to cache
|
|
|
+ IDistributedSuperFile *sfile = file->querySuperFile();
|
|
|
+ if (sfile)
|
|
|
+ {
|
|
|
+ Owned<IDistributedFileIterator> iter = sfile->getSubFileIterator();
|
|
|
+ ForEach(*iter)
|
|
|
+ {
|
|
|
+ IDistributedFile *f = &iter->query();
|
|
|
+ trackedFile->noteAddSubFile(f);
|
|
|
+ addFile(f);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ virtual void ensureFile(IDistributedFile *file)
|
|
|
+ {
|
|
|
+ if (!trackedFiles.find(file))
|
|
|
+ addFile(file);
|
|
|
+ }
|
|
|
+ virtual void clearFile(IDistributedFile *file)
|
|
|
{
|
|
|
CTransactionFile *trackedFile = lookupTrackedFile(file);
|
|
|
IDistributedSuperFile *sfile = file->querySuperFile();
|
|
@@ -1785,31 +1701,108 @@ public:
|
|
|
trackedFilesByName.removeExact(trackedFile);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- IUserDescriptor *queryUser()
|
|
|
+ virtual void clearFiles()
|
|
|
{
|
|
|
- return udesc;
|
|
|
+ trackedFiles.kill();
|
|
|
+ trackedFilesByName.kill();
|
|
|
+ if (owner)
|
|
|
+ addFile(owner); // ensure remains tracked
|
|
|
}
|
|
|
-
|
|
|
- bool addDelayedDelete(CDfsLogicalFileName &lfn,unsigned timeoutms)
|
|
|
+ virtual void noteAddSubFile(IDistributedSuperFile *super, const char *superName, IDistributedFile *sub)
|
|
|
+ {
|
|
|
+ CTransactionFile *trackedSuper = queryCreate(superName, super);
|
|
|
+ trackedSuper->noteAddSubFile(sub);
|
|
|
+ }
|
|
|
+ virtual void noteRemoveSubFile(IDistributedSuperFile *super, IDistributedFile *sub)
|
|
|
+ {
|
|
|
+ CTransactionFile *trackedSuper = lookupTrackedFile(super);
|
|
|
+ if (trackedSuper)
|
|
|
+ trackedSuper->noteRemoveSubFile(sub);
|
|
|
+ }
|
|
|
+ virtual void noteSuperSwap(IDistributedSuperFile *super1, IDistributedSuperFile *super2)
|
|
|
+ {
|
|
|
+ CTransactionFile *trackedSuper1 = lookupTrackedFile(super1);
|
|
|
+ CTransactionFile *trackedSuper2 = lookupTrackedFile(super2);
|
|
|
+ assertex(trackedSuper1 && trackedSuper2);
|
|
|
+ ICopyArrayOf<IDistributedFile> super1Subs, super2Subs;
|
|
|
+ Owned<IDistributedFileIterator> iter = trackedSuper1->getSubFiles();
|
|
|
+ ForEach(*iter)
|
|
|
+ super1Subs.append(iter->query());
|
|
|
+ trackedSuper1->clearSubs();
|
|
|
+ iter.setown(trackedSuper2->getSubFiles());
|
|
|
+ ForEach(*iter)
|
|
|
+ super2Subs.append(iter->query());
|
|
|
+ trackedSuper2->clearSubs();
|
|
|
+ ForEachItemIn(s, super2Subs)
|
|
|
+ trackedSuper1->noteAddSubFile(&super2Subs.item(s));
|
|
|
+ ForEachItemIn(s2, super1Subs)
|
|
|
+ trackedSuper2->noteAddSubFile(&super1Subs.item(s2));
|
|
|
+ }
|
|
|
+ virtual void clearSubFiles(IDistributedSuperFile *super)
|
|
|
+ {
|
|
|
+ CTransactionFile *trackedSuper = lookupTrackedFile(super);
|
|
|
+ if (trackedSuper)
|
|
|
+ trackedSuper->clearSubs();
|
|
|
+ }
|
|
|
+ virtual void noteRename(IDistributedFile *file, const char *newName)
|
|
|
+ {
|
|
|
+ CTransactionFile *trackedFile = lookupTrackedFile(file);
|
|
|
+ if (trackedFile)
|
|
|
+ {
|
|
|
+ trackedFiles.removeExact(trackedFile);
|
|
|
+ trackedFilesByName.removeExact(trackedFile);
|
|
|
+ trackedFile = queryCreate(newName, file);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ virtual void validateAddSubFile(IDistributedSuperFile *super, IDistributedFile *sub, const char *subName);
|
|
|
+ virtual bool isSubFile(IDistributedSuperFile *super, const char *subFile, bool sub)
|
|
|
+ {
|
|
|
+ CTransactionFile *trackedSuper = lookupTrackedFile(super);
|
|
|
+ if (!trackedSuper)
|
|
|
+ return false;
|
|
|
+ return trackedSuper->find(subFile, sub);
|
|
|
+ }
|
|
|
+ virtual bool addDelayedDelete(CDfsLogicalFileName &lfn,unsigned timeoutms)
|
|
|
{
|
|
|
delayeddelete.append(*new CDelayedDelete(lfn,udesc,timeoutms));
|
|
|
return true;
|
|
|
}
|
|
|
-
|
|
|
- void deleteFiles() // no rollback at this point
|
|
|
+ virtual bool prepareActions()
|
|
|
{
|
|
|
- Owned<IMultiException> me = MakeMultiException("Transaction");
|
|
|
- ForEachItemIn(i,delayeddelete) {
|
|
|
- try {
|
|
|
- delayeddelete.item(i).doDelete();
|
|
|
- } catch (IException *e) {
|
|
|
- me->append(*e);
|
|
|
- }
|
|
|
+ prepared = 0;
|
|
|
+ unsigned toPrepare = actions.ordinality();
|
|
|
+ ForEachItemIn(i0,actions)
|
|
|
+ {
|
|
|
+ if (actions.item(i0).prepare())
|
|
|
+ ++prepared;
|
|
|
+ else
|
|
|
+ break;
|
|
|
}
|
|
|
- delayeddelete.kill();
|
|
|
- if (me->ordinality())
|
|
|
- throw me.getClear();
|
|
|
+ return prepared == toPrepare;
|
|
|
+ }
|
|
|
+ virtual void retryActions()
|
|
|
+ {
|
|
|
+ clearFiles(); // clear all previously tracked pending file changes, e.g. renames, super file additions/removals
|
|
|
+ while (prepared) // unlock for retry
|
|
|
+ actions.item(--prepared).retry();
|
|
|
+ }
|
|
|
+ virtual void runActions()
|
|
|
+ {
|
|
|
+ ForEachItemIn(i,actions)
|
|
|
+ actions.item(i).run();
|
|
|
+ }
|
|
|
+ virtual void commitAndClearup()
|
|
|
+ {
|
|
|
+ // =============== COMMIT and CLEANUP
|
|
|
+ commitActions();
|
|
|
+ clearFiles();
|
|
|
+ isactive = false;
|
|
|
+ actions.kill();
|
|
|
+ deleteFiles();
|
|
|
+ }
|
|
|
+ virtual ICodeContext *queryCodeContext()
|
|
|
+ {
|
|
|
+ return codeCtx;
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -3197,7 +3190,7 @@ protected:
|
|
|
parts.item(i1++).clearDirty();
|
|
|
}
|
|
|
}
|
|
|
- void detach(unsigned timeoutMs=INFINITE, bool removePhysicals=true)
|
|
|
+ void detach(unsigned timeoutMs, bool removePhysicals, ICodeContext *ctx)
|
|
|
{
|
|
|
// Removes either a cluster in case of multi cluster file or the whole File entry from DFS
|
|
|
|
|
@@ -3943,13 +3936,13 @@ public:
|
|
|
public:
|
|
|
void detachLogical(unsigned timeoutms=INFINITE)
|
|
|
{
|
|
|
- detach(timeoutms, false);
|
|
|
+ detach(timeoutms, false, NULL);
|
|
|
}
|
|
|
|
|
|
public:
|
|
|
- virtual void detach(unsigned timeoutMs=INFINITE)
|
|
|
+ virtual void detach(unsigned timeoutMs=INFINITE, ICodeContext *ctx=NULL)
|
|
|
{
|
|
|
- detach(timeoutMs, true);
|
|
|
+ detach(timeoutMs, true, ctx);
|
|
|
}
|
|
|
|
|
|
bool existsPhysicalPartFiles(unsigned short port)
|
|
@@ -4931,7 +4924,7 @@ protected:
|
|
|
int interleaved; // 0 not interleaved, 1 interleaved old, 2 interleaved new
|
|
|
IArrayOf<IDistributedFile> subfiles;
|
|
|
|
|
|
- void clearSuperOwners(unsigned timeoutMs)
|
|
|
+ void clearSuperOwners(unsigned timeoutMs, ICodeContext *ctx)
|
|
|
{
|
|
|
/* JCSMORE - Why on earth is this doing this way?
|
|
|
* We are in a super file, we already have [read] locks to sub files (in 'subfiles' array)
|
|
@@ -4940,7 +4933,6 @@ protected:
|
|
|
Owned<IPropertyTreeIterator> iter = root->getElements("SubFile");
|
|
|
StringBuffer oquery;
|
|
|
oquery.append("SuperOwner[@name=\"").append(logicalName.get()).append("\"]");
|
|
|
- Owned<IMultiException> exceptions = MakeMultiException("CDelayedDelete::doRemoveEntry::SuperOwners");
|
|
|
ForEach(*iter)
|
|
|
{
|
|
|
const char *name = iter->query().queryProp("@name");
|
|
@@ -4957,13 +4949,20 @@ protected:
|
|
|
if (subfroot)
|
|
|
{
|
|
|
if (!subfroot->removeProp(oquery.str()))
|
|
|
- exceptions->append(*MakeStringException(-1, "CDelayedDelete::removeEntry: SubFile %s of %s not found for removal",name?name:"(NULL)", logicalName.get()));
|
|
|
+ {
|
|
|
+ VStringBuffer s("SubFile %s is not owned by SuperFile %s", name, logicalName.get());
|
|
|
+ if (ctx)
|
|
|
+ ctx->addWuException(s.str(), 0, SeverityWarning, "DFS[clearSuperOwner]");
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Owned<IException> e = makeStringException(-1, s.str());
|
|
|
+ EXCLOG(e, "DFS[clearSuperOwner]");
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if (exceptions->ordinality())
|
|
|
- throw exceptions.getClear();
|
|
|
}
|
|
|
|
|
|
static StringBuffer &getSubPath(StringBuffer &path,unsigned idx)
|
|
@@ -5529,7 +5528,7 @@ public:
|
|
|
loadSubFiles(NULL, 0, true);
|
|
|
}
|
|
|
|
|
|
- void detach(unsigned timeoutMs=INFINITE)
|
|
|
+ void detach(unsigned timeoutMs=INFINITE, ICodeContext *ctx=NULL)
|
|
|
{
|
|
|
assertex(conn.get()); // must be attached
|
|
|
CriticalBlock block(sect);
|
|
@@ -5551,7 +5550,7 @@ public:
|
|
|
* 5) updateFS (housekeeping of empty scopes, relationships) - ok
|
|
|
*/
|
|
|
CFileChangeWriteLock writeLock(conn, timeoutMs);
|
|
|
- clearSuperOwners(timeoutMs);
|
|
|
+ clearSuperOwners(timeoutMs, ctx);
|
|
|
writeLock.clear();
|
|
|
root.setown(closeConnection(true));
|
|
|
updateFS(logicalName, parent->queryDefaultTimeout());
|
|
@@ -7753,7 +7752,7 @@ public:
|
|
|
{
|
|
|
if (nestedTransaction)
|
|
|
nestedTransaction->runActions();
|
|
|
- super->detach();
|
|
|
+ super->detach(INFINITE, transaction->queryCodeContext());
|
|
|
}
|
|
|
virtual void commit()
|
|
|
{
|
|
@@ -10692,9 +10691,9 @@ IDaliServer *createDaliDFSServer(IPropertyTree *config)
|
|
|
return daliDFSServer;
|
|
|
}
|
|
|
|
|
|
-IDistributedFileTransaction *createDistributedFileTransaction(IUserDescriptor *user)
|
|
|
+IDistributedFileTransaction *createDistributedFileTransaction(IUserDescriptor *user, ICodeContext *ctx)
|
|
|
{
|
|
|
- return new CDistributedFileTransaction(user);
|
|
|
+ return new CDistributedFileTransaction(user, NULL, ctx);
|
|
|
}
|
|
|
|
|
|
static void encodeCompareResult(DistributedFileCompareResult &ret,bool differs,CDateTime &newestdt1,CDateTime &newestdt2)
|