Browse Source

HPCC-13797 Add support for WU locking in Cassandra

Remove the unused (well, used once, incorrectly) option to lock a workunit for
reading.

Use dali to support locking and abort requests in Cassandra workunits.

Signed-off-by: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 10 years ago
parent
commit
554f7c2bec

+ 2 - 2
common/fileview2/fvdisksource.cpp

@@ -670,7 +670,7 @@ bool TranslatedDiskDataSource::init()
         return false;
 
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-    Owned<IConstWorkUnit> wu = factory->openWorkUnit(helperWuid, false);
+    Owned<IConstWorkUnit> wu = factory->openWorkUnit(helperWuid);
     Owned<IConstWUResult> dataResult = wu->getResultBySequence(0);
     directSource.setown(new WorkunitDiskDataSource(logicalName, dataResult, helperWuid, username.get(), password.get()));
     return directSource->init();
@@ -789,7 +789,7 @@ bool IndirectDiskDataSource::loadBlock(__int64 startRow, offset_t startOffset)
 
     //Now extract the results...
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-    Owned<IConstWorkUnit> wu = factory->openWorkUnit(browseWuid, false);
+    Owned<IConstWorkUnit> wu = factory->openWorkUnit(browseWuid);
     Owned<IConstWUResult> dataResult = wu->getResultBySequence(0);
     MemoryBuffer2IDataVal xxx(temp); dataResult->getResultRaw(xxx, NULL, NULL);
 

+ 2 - 2
common/fileview2/fvdsremote.cpp

@@ -589,13 +589,13 @@ extern FILEVIEW_API void stopRemoteDataSourceServer()
 IConstWUResult * resolveResult(const char * wuid, unsigned sequence, const char * name)
 {
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-    Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid, false);
+    Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid);
     return getWorkUnitResult(wu, name, sequence);
 }
 
 IConstWUResult * secResolveResult(ISecManager &secmgr, ISecUser &secuser, const char * wuid, unsigned sequence, const char * name)
 {
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-    Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid, false, &secmgr, &secuser);
+    Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid, &secmgr, &secuser);
     return (wu) ? getWorkUnitResult(wu, name, sequence) : NULL;
 }

+ 2 - 2
common/fileview2/fvquerysource.cpp

@@ -69,7 +69,7 @@ bool QueryDataSource::createBrowseWU()
     returnedRecord.set(browseWUcode->queryChild(0)->queryRecord());
 
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-    Owned<IConstWorkUnit> parent = factory->openWorkUnit(wuid, false);
+    Owned<IConstWorkUnit> parent = factory->openWorkUnit(wuid);
 
     const char *user = parent->queryUser();
     Owned<IWorkUnit> workunit = factory->createWorkUnit("fileViewer", user);
@@ -152,7 +152,7 @@ bool QueryDataSource::loadBlock(__int64 startRow, offset_t startOffset)
 
     //Now extract the results...
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-    Owned<IConstWorkUnit> wu = factory->openWorkUnit(browseWuid, false);
+    Owned<IConstWorkUnit> wu = factory->openWorkUnit(browseWuid);
     Owned<IConstWUResult> dataResult = wu->getResultBySequence(0);
     MemoryBuffer2IDataVal xxx(temp); dataResult->getResultRaw(xxx, NULL, NULL);
 

+ 1 - 1
common/fileview2/fvsource.cpp

@@ -1062,7 +1062,7 @@ void FVDataSource::loadDll(const char * wuid)
 {
     //MORE: This code should be commoned up and available in the work unit code or something...
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-    Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid, false);
+    Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid);
 
     //Plugins should already be loaded when they were registered with the ViewTransformerRegistry
     //Something like the following code could be used to check the plugin version...

+ 2 - 2
common/workunit/pkgimpl.hpp

@@ -410,7 +410,7 @@ public:
             throw MakeStringException(PACKAGE_QUERY_NOT_FOUND, "Query %s not found", queryname);
         Owned<IReferencedFileList> filelist = createReferencedFileList(NULL, true, false);
         Owned<IWorkUnitFactory> wufactory = getWorkUnitFactory(NULL, NULL);
-        Owned<IConstWorkUnit> cw = wufactory->openWorkUnit(query->queryProp("@wuid"), false);
+        Owned<IConstWorkUnit> cw = wufactory->openWorkUnit(query->queryProp("@wuid"));
 
         const IHpccPackage *pkg = matchPackage(query->queryProp("@id"));
         filelist->addFilesFromQuery(cw, pkg);
@@ -503,7 +503,7 @@ public:
             if (queryid && *queryid)
             {
                 Owned<IReferencedFileList> filelist = createReferencedFileList(NULL, true, false);
-                Owned<IConstWorkUnit> cw = wufactory->openWorkUnit(queries->query().queryProp("@wuid"), false);
+                Owned<IConstWorkUnit> cw = wufactory->openWorkUnit(queries->query().queryProp("@wuid"));
 
                 StringArray libnames, unresolvedLibs;
                 gatherLibraryNames(libnames, unresolvedLibs, *wufactory, *cw, qs);

+ 14 - 105
common/workunit/workunit.cpp

@@ -53,8 +53,6 @@
 
 #define GLOBAL_WORKUNIT "global"
 
-#define SDS_LOCK_TIMEOUT (5*60*1000) // 5mins, 30s a bit short
-
 static int workUnitTraceLevel = 1;
 
 static StringBuffer &getXPath(StringBuffer &wuRoot, const char *wuid)
@@ -1075,27 +1073,25 @@ extern IConstWorkUnitInfo *createConstWorkUnitInfo(IPropertyTree &p)
     return new CLightweightWorkunitInfo(p);
 }
 
-class CDaliWorkUnit : public CLocalWorkUnit
+class CDaliWorkUnit : public CPersistedWorkUnit
 {
 public:
     IMPLEMENT_IINTERFACE;
     CDaliWorkUnit(IRemoteConnection *_conn, ISecManager *secmgr, ISecUser *secuser)
-        : connection(_conn), CLocalWorkUnit(secmgr, secuser)
+        : connection(_conn), CPersistedWorkUnit(secmgr, secuser)
     {
         loadPTree(connection->getRoot());
-        abortDirty = true;
-        abortState = false;
     }
     ~CDaliWorkUnit()
     {
         // NOTE - order is important - we need to construct connection before p and (especially) destroy after p
-        // We use the beforeDIspose() in base class to help ensure this
+        // We use the beforeDispose() in base class to help ensure this
         p.clear();
     }
 
     virtual void forceReload()
     {
-        synchronized sync(locked); // protect locked workunits (uncommited writes) from reload
+        synchronized sync(locked); // protect locked workunits (uncommitted writes) from reload
         StringBuffer wuRoot;
         getXPath(wuRoot, p->queryName());
         IRemoteConnection *newconn = querySDS().connect(wuRoot.str(), myProcessSession(), 0, SDS_LOCK_TIMEOUT);
@@ -1110,14 +1106,14 @@ public:
 
     virtual void cleanupAndDelete(bool deldll, bool deleteOwned, const StringArray *deleteExclusions)
     {
-        CLocalWorkUnit::cleanupAndDelete(deldll, deleteOwned, deleteExclusions);
+        CPersistedWorkUnit::cleanupAndDelete(deldll, deleteOwned, deleteExclusions);
         connection->close(true);
         connection.clear();
     }
 
     virtual void commit()
     {
-        CLocalWorkUnit::commit();
+        CPersistedWorkUnit::commit();
         if (connection)
             connection->commit();
     }
@@ -1133,7 +1129,6 @@ public:
         if (!connection)
             throw MakeStringException(WUERR_LockFailed, "Failed to get connection for xpath %s", wuRoot.str());
         clearCached(true);
-        abortDirty = true;
         p.setown(connection->getRoot());
     }
 
@@ -1161,80 +1156,8 @@ public:
             throw;
         }
     }
-
-    virtual void subscribe(WUSubscribeOptions options)
-    {
-        CriticalBlock block(crit);
-        assertex(options==SubscribeOptionAbort);
-        if (!abortWatcher)
-        {
-            abortWatcher.setown(new CWorkUnitAbortWatcher(this, p->queryName()));
-            abortDirty = true;
-        }
-    }
-
-    virtual void unsubscribe()
-    {
-        CriticalBlock block(crit);
-        if (abortWatcher)
-        {
-            abortWatcher->unsubscribe();
-            abortWatcher.clear();
-        }
-    }
-
-    virtual bool aborting() const
-    {
-        CriticalBlock block(crit);
-        if (abortDirty)
-        {
-            StringBuffer apath;
-            apath.append("/WorkUnitAborts/").append(p->queryName());
-            Owned<IRemoteConnection> acon = querySDS().connect(apath.str(), myProcessSession(), 0, SDS_LOCK_TIMEOUT);
-            if (acon)
-                abortState = acon->queryRoot()->getPropInt(NULL) != 0;
-            else
-                abortState = false;
-            abortDirty = false;
-        }
-        return abortState;
-    }
-
 protected:
-    class CWorkUnitAbortWatcher : public CInterface, implements ISDSSubscription
-    {
-        CDaliWorkUnit *parent; // not linked - it links me
-        SubscriptionId abort;
-    public:
-        IMPLEMENT_IINTERFACE;
-        CWorkUnitAbortWatcher(CDaliWorkUnit *_parent, const char *wuid) : parent(_parent)
-        {
-            StringBuffer wuRoot;
-            wuRoot.append("/WorkUnitAborts/").append(wuid);
-            abort = querySDS().subscribe(wuRoot.str(), *this);
-        }
-        ~CWorkUnitAbortWatcher()
-        {
-            assertex(abort==0);
-        }
-
-        void unsubscribe()
-        {
-            querySDS().unsubscribe(abort);
-            abort = 0;
-        }
-
-        void notify(SubscriptionId id, const char *xpath, SDSNotifyFlags flags, unsigned valueLen, const void *valueData)
-        {
-            parent->abortDirty = true;
-        }
-    };
-
     Owned<IRemoteConnection> connection;
-    Owned<CWorkUnitAbortWatcher> abortWatcher;
-
-    mutable bool abortDirty;
-    mutable bool abortState;
 };
 
 class CLockedWorkUnit : public CInterface, implements ILocalWorkUnit, implements IExtendedWUInterface
@@ -2270,7 +2193,7 @@ bool CWorkUnitFactory::deleteWorkUnit(const char * wuid, ISecManager *secmgr, IS
     return true;
 }
 
-IConstWorkUnit* CWorkUnitFactory::openWorkUnit(const char *wuid, bool lock, ISecManager *secmgr, ISecUser *secuser)
+IConstWorkUnit* CWorkUnitFactory::openWorkUnit(const char *wuid, ISecManager *secmgr, ISecUser *secuser)
 {
     StringBuffer wuidStr(wuid);
     wuidStr.trim();
@@ -2287,7 +2210,7 @@ IConstWorkUnit* CWorkUnitFactory::openWorkUnit(const char *wuid, bool lock, ISec
 
     if (workUnitTraceLevel > 1)
         PrintLog("openWorkUnit %s", wuidStr.str());
-    Owned<IConstWorkUnit> wu = _openWorkUnit(wuid, lock, secmgr, secuser);
+    Owned<IConstWorkUnit> wu = _openWorkUnit(wuid, secmgr, secuser);
     if (wu)
     {
         if (!checkWuSecAccess(*wu, secmgr, secuser, SecAccess_Read, "opening", true, true))
@@ -2616,11 +2539,11 @@ public:
         return new CDaliWorkUnit(conn, secmgr, secuser);
     }
 
-    virtual CLocalWorkUnit* _openWorkUnit(const char *wuid, bool lock, ISecManager *secmgr, ISecUser *secuser)
+    virtual CLocalWorkUnit* _openWorkUnit(const char *wuid, ISecManager *secmgr, ISecUser *secuser)
     {
         StringBuffer wuRoot;
         getXPath(wuRoot, wuid);
-        IRemoteConnection* conn = sdsManager->connect(wuRoot.str(), session, lock ? RTM_LOCK_READ|RTM_LOCK_SUB : 0, SDS_LOCK_TIMEOUT);
+        IRemoteConnection* conn = sdsManager->connect(wuRoot.str(), session, 0, SDS_LOCK_TIMEOUT);
         if (conn)
             return new CDaliWorkUnit(conn, secmgr, secuser);
         else
@@ -3088,11 +3011,11 @@ public:
         if (!secUser) secUser = defaultSecUser.get();
         return baseFactory->deleteWorkUnit(wuid, secMgr, secUser);
     }
-    virtual IConstWorkUnit* openWorkUnit(const char *wuid, bool lock, ISecManager *secMgr, ISecUser *secUser)
+    virtual IConstWorkUnit* openWorkUnit(const char *wuid, ISecManager *secMgr, ISecUser *secUser)
     {
         if (!secMgr) secMgr = defaultSecMgr.get();
         if (!secUser) secUser = defaultSecUser.get();
-        return baseFactory->openWorkUnit(wuid, lock, secMgr, secUser);
+        return baseFactory->openWorkUnit(wuid, secMgr, secUser);
     }
     virtual IWorkUnit* updateWorkUnit(const char *wuid, ISecManager *secMgr, ISecUser *secUser)
     {
@@ -3753,10 +3676,6 @@ void CLocalWorkUnit::requestAbort()
     abortWorkUnit(p->queryName());
 }
 
-void CLocalWorkUnit::subscribe(WUSubscribeOptions options)
-{
-}
-
 void CLocalWorkUnit::unlockRemote()
 {
     CriticalBlock block(crit);
@@ -4040,11 +3959,6 @@ void CLocalWorkUnit::setAgentSession(__int64 sessionId)
     p->setPropInt64("@agentSession", sessionId);
 }
 
-bool CLocalWorkUnit::aborting() const 
-{
-    return false;
-}
-
 bool CLocalWorkUnit::getIsQueryService() const 
 {
     CriticalBlock block(crit);
@@ -5814,11 +5728,6 @@ IWULibrary* CLocalWorkUnit::updateLibraryByName(const char *qname)
     return q;
 }
 
-void CLocalWorkUnit::unsubscribe()
-{
-    // Only overriding versions need to do anything
-}
-
 void CLocalWorkUnit::_loadExceptions() const
 {
     assertex(exceptions.length() == 0);
@@ -9434,7 +9343,7 @@ extern WORKUNIT_API bool secDebugWorkunit(const char * wuid, ISecManager &secmgr
 {
     if (strnicmp(command, "<debug:", 7) == 0 && checkWuSecAccess(wuid, &secmgr, &secuser, SecAccess_Read, "Debug", false, true))
     {
-        Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid, false, &secmgr, &secuser);
+        Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid, &secmgr, &secuser);
         SCMStringBuffer ip;
         unsigned port;
         port = wu->getDebugAgentListenerPort();
@@ -10332,7 +10241,7 @@ extern WORKUNIT_API void gatherLibraryNames(StringArray &names, StringArray &unr
         if (query && query->getPropBool("@isLibrary"))
         {
             const char *wuid = query->queryProp("@wuid");
-            Owned<IConstWorkUnit> libcw = workunitFactory.openWorkUnit(wuid, false);
+            Owned<IConstWorkUnit> libcw = workunitFactory.openWorkUnit(wuid);
             if (libcw)
             {
                 names.appendUniq(libname.str());

+ 1 - 1
common/workunit/workunit.hpp

@@ -1252,7 +1252,7 @@ interface IWorkUnitFactory : extends IInterface
 {
     virtual IWorkUnit *createWorkUnit(const char *app, const char *scope, ISecManager *secmgr = NULL, ISecUser *secuser = NULL) = 0;
     virtual bool deleteWorkUnit(const char *wuid, ISecManager *secmgr = NULL, ISecUser *secuser = NULL) = 0;
-    virtual IConstWorkUnit * openWorkUnit(const char *wuid, bool lock, ISecManager *secmgr = NULL, ISecUser *secuser = NULL) = 0;
+    virtual IConstWorkUnit * openWorkUnit(const char *wuid, ISecManager *secmgr = NULL, ISecUser *secuser = NULL) = 0;
     virtual IConstWorkUnitIterator * getWorkUnitsByOwner(const char * owner, ISecManager *secmgr = NULL, ISecUser *secuser = NULL) = 0;
     virtual IWorkUnit * updateWorkUnit(const char * wuid, ISecManager *secmgr = NULL, ISecUser *secuser = NULL) = 0;
     virtual int setTracingLevel(int newlevel) = 0;

+ 89 - 6
common/workunit/workunit.ipp

@@ -18,8 +18,11 @@
 #ifndef WORKUNIT_IPP_INCL
 #include "seclib.hpp"
 #include "dasess.hpp"  /// For IUserDescriptor
+#include "dasds.hpp"
 #include "workunit.hpp"
 
+#define SDS_LOCK_TIMEOUT (5*60*1000) // 5 mins
+
 class CLocalWUAppValue : public CInterface, implements IConstWUAppValue
 {
     Owned<IPropertyTree> p;
@@ -210,7 +213,7 @@ public:
     ISecManager *querySecMgr() { return secMgr.get(); }
     ISecUser *querySecUser() { return secUser.get(); }
 
-    virtual bool aborting() const;
+    virtual bool aborting() const { return false; }
     virtual void forceReload() {};
     virtual WUAction getAction() const;
     virtual const char *queryActionDesc() const;
@@ -289,7 +292,6 @@ public:
     virtual bool isPausing() const;
     virtual IWorkUnit& lock();
     virtual void requestAbort();
-    virtual void subscribe(WUSubscribeOptions options);
     virtual unsigned calculateHash(unsigned prevHash);
     virtual void copyWorkUnit(IConstWorkUnit *cached, bool all);
     virtual IPropertyTree *queryPTree() const;
@@ -376,6 +378,7 @@ public:
     void deleteTemporaries();
     void addDiskUsageStats(__int64 avgNodeUsage, unsigned minNode, __int64 minNodeUsage, unsigned maxNode, __int64 maxNodeUsage, __int64 graphId);
     void setTimeScheduled(const IJlibDateTime &val);
+    virtual void subscribe(WUSubscribeOptions options) {};
 
 // ILocalWorkUnit - used for debugging etc
     void loadXML(const char *xml);
@@ -503,7 +506,6 @@ public:
         }
     }
 
-protected:
     IWUResult *updateResult(const char *name, unsigned sequence)
     {
         Owned <IWUResult> result = updateWorkUnitResult(this, name, sequence);
@@ -555,9 +557,9 @@ protected:
     }
 
     // Implemented by derived classes
+    virtual void unsubscribe() {};
     virtual void _lockRemote() {};
     virtual void _unlockRemote() {};
-    virtual void unsubscribe();
     virtual void _loadFilesRead() const;
     virtual void _loadResults() const;
     virtual void _loadVariables() const;
@@ -566,6 +568,87 @@ protected:
     virtual void _loadExceptions() const;
 };
 
+class CPersistedWorkUnit : public CLocalWorkUnit
+{
+public:
+    CPersistedWorkUnit(ISecManager *secmgr, ISecUser *secuser) : CLocalWorkUnit(secmgr, secuser)
+{
+        abortDirty = true;
+        abortState = false;
+    }
+
+    virtual void subscribe(WUSubscribeOptions options)
+    {
+        CriticalBlock block(crit);
+        assertex(options==SubscribeOptionAbort);
+        if (!abortWatcher)
+        {
+            abortWatcher.setown(new CWorkUnitAbortWatcher(this, p->queryName()));
+            abortDirty = true;
+        }
+    }
+    virtual void unsubscribe()
+    {
+        CriticalBlock block(crit);
+        if (abortWatcher)
+        {
+            abortWatcher->unsubscribe();
+            abortWatcher.clear();
+        }
+    }
+
+    virtual bool aborting() const
+    {
+        CriticalBlock block(crit);
+        if (abortDirty)
+        {
+            StringBuffer apath;
+            apath.append("/WorkUnitAborts/").append(p->queryName());
+            Owned<IRemoteConnection> acon = querySDS().connect(apath.str(), myProcessSession(), 0, SDS_LOCK_TIMEOUT);
+            if (acon)
+                abortState = acon->queryRoot()->getPropInt(NULL) != 0;
+            else
+                abortState = false;
+            abortDirty = false;
+        }
+        return abortState;
+    }
+
+protected:
+    class CWorkUnitAbortWatcher : public CInterface, implements ISDSSubscription
+    {
+        CPersistedWorkUnit *parent; // not linked - it links me
+        SubscriptionId abort;
+    public:
+        IMPLEMENT_IINTERFACE;
+        CWorkUnitAbortWatcher(CPersistedWorkUnit *_parent, const char *wuid) : parent(_parent)
+        {
+            StringBuffer wuRoot;
+            wuRoot.append("/WorkUnitAborts/").append(wuid);
+            abort = querySDS().subscribe(wuRoot.str(), *this);
+        }
+        ~CWorkUnitAbortWatcher()
+        {
+            assertex(abort==0);
+        }
+
+        void unsubscribe()
+        {
+            querySDS().unsubscribe(abort);
+            abort = 0;
+        }
+
+        void notify(SubscriptionId id, const char *xpath, SDSNotifyFlags flags, unsigned valueLen, const void *valueData)
+        {
+            parent->abortDirty = true;
+        }
+    };
+
+    Owned<CWorkUnitAbortWatcher> abortWatcher;
+    mutable bool abortDirty;
+    mutable bool abortState;
+};
+
 interface ISDSManager; // MORE - can remove once dali split out
 
 class CWorkUnitFactory : public CInterface, implements IWorkUnitFactory
@@ -580,7 +663,7 @@ public:
 
     virtual IWorkUnit * createWorkUnit(const char * app, const char * user, ISecManager *secmgr, ISecUser *secuser);
     virtual bool deleteWorkUnit(const char * wuid, ISecManager *secmgr, ISecUser *secuser);
-    virtual IConstWorkUnit * openWorkUnit(const char * wuid, bool lock, ISecManager *secmgr, ISecUser *secuser);
+    virtual IConstWorkUnit * openWorkUnit(const char * wuid, ISecManager *secmgr, ISecUser *secuser);
     virtual IWorkUnit * updateWorkUnit(const char * wuid, ISecManager *secmgr, ISecUser *secuser);
     virtual int setTracingLevel(int newlevel);
     virtual IWorkUnit * createNamedWorkUnit(const char * wuid, const char * app, const char *scope, ISecManager *secmgr, ISecUser *secuser);
@@ -611,7 +694,7 @@ public:
 protected:
     // These need to be implemented by the derived classes
     virtual CLocalWorkUnit* _createWorkUnit(const char *wuid, ISecManager *secmgr, ISecUser *secuser) = 0;
-    virtual CLocalWorkUnit* _openWorkUnit(const char *wuid, bool lock, ISecManager *secmgr, ISecUser *secuser) = 0;  // for read access
+    virtual CLocalWorkUnit* _openWorkUnit(const char *wuid, ISecManager *secmgr, ISecUser *secuser) = 0;  // for read access
     virtual CLocalWorkUnit* _updateWorkUnit(const char *wuid, ISecManager *secmgr, ISecUser *secuser) = 0;  // for write access
 
 };

+ 1 - 1
common/workunit/wujobq.cpp

@@ -2123,7 +2123,7 @@ extern bool WORKUNIT_API runWorkUnit(const char *wuid, const char *cluster)
 extern bool WORKUNIT_API runWorkUnit(const char *wuid)
 {
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-    Owned<IConstWorkUnit> w = factory->openWorkUnit(wuid, false);
+    Owned<IConstWorkUnit> w = factory->openWorkUnit(wuid);
     if (w)
     {
         StringAttr clusterName = (w->queryClusterName());

+ 1 - 1
common/wuwebview/wuwebview.cpp

@@ -804,7 +804,7 @@ void WuWebView::setWorkunit(IConstWorkUnit &_cw)
 void WuWebView::setWorkunit(const char *wuid)
 {
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-    Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid, false);
+    Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid);
     if (!wu)
         throw MakeStringException(WUWEBERR_WorkUnitNotFound, "Workunit not found %s", wuid);
     setWorkunit(*wu);

+ 4 - 4
dali/daliadmin/daliadmin.cpp

@@ -2416,14 +2416,14 @@ static void unlock(const char *pattern)
 static void dumpWorkunit(const char *wuid, bool includeProgress)
 {
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-    Owned<IConstWorkUnit> workunit = factory->openWorkUnit(wuid, false);
+    Owned<IConstWorkUnit> workunit = factory->openWorkUnit(wuid);
     exportWorkUnitToXMLFile(workunit, "stdout:", 0, true, includeProgress, true);
 }
 
 static void dumpProgress(const char *wuid, const char * graph)
 {
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-    Owned<IConstWorkUnit> workunit = factory->openWorkUnit(wuid, false);
+    Owned<IConstWorkUnit> workunit = factory->openWorkUnit(wuid);
     if (!workunit)
         return;
     Owned<IConstWUGraphProgress> progress = workunit->getGraphProgress(graph);
@@ -2443,7 +2443,7 @@ static const char * checkDash(const char * s)
 static void dumpStats(const char *wuid, const char * creatorTypeText, const char * creator, const char * scopeTypeText, const char * scope, const char * kindText)
 {
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-    Owned<IConstWorkUnit> workunit = factory->openWorkUnit(wuid, false);
+    Owned<IConstWorkUnit> workunit = factory->openWorkUnit(wuid);
     if (!workunit)
         return;
 
@@ -2516,7 +2516,7 @@ static void wuidCompress(const char *match, const char *type, bool compress)
     ForEach(*iter)
     {
         const char *wuid = iter->query().queryName();
-        IConstWorkUnit &wu = *factory->openWorkUnit(wuid, false);
+        IConstWorkUnit &wu = *factory->openWorkUnit(wuid);
 
         StringArray graphNames;
         Owned<IConstWUGraphIterator> graphIter = &wu.getGraphs(GraphTypeAny);

+ 2 - 2
dali/sasha/saarch.cpp

@@ -601,9 +601,9 @@ static bool doArchiveWorkUnit(IWorkUnitFactory *wufactory,const char *wuid, Stri
         res.append("BACKUP: ");
     res.append(wuid).append(" ");
     if (wufactory) {
-        Owned<IConstWorkUnit> wu;
+        Owned<IWorkUnit> wu;
         try {
-            wu.setown(wufactory->openWorkUnit(wuid, true));
+            wu.setown(wufactory->updateWorkUnit(wuid));
         }
         catch (IException *e) { // probably locked
             e->errorMessage(res);

+ 4 - 4
ecl/eclagent/eclagent.cpp

@@ -725,7 +725,7 @@ IConstWUResult *EclAgent::getExternalResult(const char * wuid, const char *name,
 {
     LOG(MCsetresult, unknownJob, "EclAgent::getExternalResult(wuid:'%s',name='%s',sequence:%d)", nullText(wuid), nullText(name), sequence);
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-    Owned<IConstWorkUnit> externalWU = factory->openWorkUnit(wuid, false);
+    Owned<IConstWorkUnit> externalWU = factory->openWorkUnit(wuid);
     if (externalWU)
     {
         externalWU->remoteCheckAccess(queryUserDescriptor(), false);
@@ -1703,7 +1703,7 @@ IConstWorkUnit * EclAgent::resolveLibrary(const char * libraryName, unsigned exp
     const char * libraryWuid = resolved->queryProp("@wuid");
 
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-    Owned<IConstWorkUnit> wu = factory->openWorkUnit(libraryWuid, false);
+    Owned<IConstWorkUnit> wu = factory->openWorkUnit(libraryWuid);
     if (!wu)
         throw MakeStringException(0, "Could not open workunit %s implementing library %s", libraryWuid, libraryName);
 
@@ -2003,7 +2003,7 @@ void EclAgent::doProcess()
             // a final attempt to commit the original error (only) to the workunit
             // since unlockWorkUnit( which commits ) can error due to the nature of the transaction.
             Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-            Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid.get(), false);
+            Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid.get());
             Owned<IWorkUnit> w = &wu->lock();
             StringBuffer m("System error ");
             m.append(e->errorCode()).append(": ");
@@ -3434,7 +3434,7 @@ extern int HTHOR_API eclagent_main(int argc, const char *argv[], StringBuffer *
 #ifdef _DEBUG
                 factory->setTracingLevel(10);
 #endif
-                w = factory->openWorkUnit(wuid.str(), false);
+                w = factory->openWorkUnit(wuid.str());
             }
             else
                 w = standAloneWorkUnit.getClear();

+ 1 - 1
ecl/eclscheduler/eclscheduler.cpp

@@ -140,7 +140,7 @@ private:
             {
                 //The work unit failed to run for some reason.. check if it has disappeared
                 Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-                Owned<IConstWorkUnit> w = factory->openWorkUnit(wuid, false);
+                Owned<IConstWorkUnit> w = factory->openWorkUnit(wuid);
                 if (!w)
                 {
                     ERRLOG("Scheduled workunit %s no longer exists - descheduling", wuid);

+ 8 - 8
ecl/wutest/wutest.cpp

@@ -306,7 +306,7 @@ int main(int argc, const char *argv[])
                 {
                     IPropertyTree &thisProgress = iter->query();
                     const char *wuid = thisProgress.queryName();
-                    Owned<IConstWorkUnit> w = factory->openWorkUnit(wuid, false);
+                    Owned<IConstWorkUnit> w = factory->openWorkUnit(wuid);
                     if (!w)
                     {
                         printf("Orphaned graph info %s\n", wuid);
@@ -333,7 +333,7 @@ int main(int argc, const char *argv[])
                         splitFilename(filename, NULL, NULL, &wuid, NULL);
                         if (wuid.charAt(0)=='W' && wuid.charAt(1)=='2' && wuid.charAt(2)=='0') // Beware the Y2100 bug...
                         {
-                            Owned<IConstWorkUnit> w = factory->openWorkUnit(wuid.str(), false);
+                            Owned<IConstWorkUnit> w = factory->openWorkUnit(wuid.str());
                             if (!w)
                             {
                                 printf("Orphaned dll info %s\n", wuid.str());
@@ -368,7 +368,7 @@ int main(int argc, const char *argv[])
                     printf("failed to restore %s\n", wuid);
             }
             else {
-                Owned<IConstWorkUnit> w = factory->openWorkUnit(globals->queryProp("WUID"), false);
+                Owned<IConstWorkUnit> w = factory->openWorkUnit(globals->queryProp("WUID"));
                 if (w)
                     dump(*w, globals);
             }
@@ -379,7 +379,7 @@ int main(int argc, const char *argv[])
             ForEach(*it)
             {
                 IConstWorkUnitInfo& wi = it->query();
-                Owned<IConstWorkUnit> w = factory->openWorkUnit(wi.queryWuid(), false);
+                Owned<IConstWorkUnit> w = factory->openWorkUnit(wi.queryWuid());
                 if (!dump(*w, globals))
                     break;
             }
@@ -712,7 +712,7 @@ protected:
         createWu.clear();
 
         // Now try to re-read
-        Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid, false);
+        Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid);
         ASSERT(streq(wu->queryWuid(), wuid));
         ASSERT(streq(wu->queryJobName(), embeddedWU->queryJobName()));
         exportWorkUnitToXML(wu, xml3, false, false, false);
@@ -854,7 +854,7 @@ protected:
         SCMStringBuffer s;
         for (i = 0; i < testSize; i++)
         {
-            Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuids.item(i), false);
+            Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuids.item(i));
             if (false)
             {
                 StringBuffer wuXML;
@@ -946,7 +946,7 @@ protected:
         start = end;
         for (i = 0; i < testSize; i++)
         {
-            Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuids.item(i), false);
+            Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuids.item(i));
             ASSERT(wu->getExceptionCount() == 0);
         }
         end = msTick();
@@ -973,7 +973,7 @@ protected:
         start = msTick();
         for (i = 0; i < testSize; i++)
         {
-            Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuids.item(i), false);
+            Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuids.item(i));
             Owned<IConstWUResult> result = wu->getResultByName("Result 1");
             ASSERT(result);
             ASSERT(result->isResultScalar());

+ 2 - 2
esp/services/ecldirect/EclDirectService.cpp

@@ -206,7 +206,7 @@ bool CEclDirectEx::onRunEcl(IEspContext &context, IEspRunEclRequest & req, IEspR
 
     if (waitForWorkUnitToComplete(wuid.str(), defaultWait))
     {
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
 
         SCMStringBuffer resultXML;
         getFullWorkUnitResultsXML(context.queryUserId(), context.queryPassword(), cw.get(), resultXML);
@@ -304,7 +304,7 @@ bool CEclDirectEx::onRunEclEx(IEspContext &context, IEspRunEclExRequest & req, I
         return true;
     }
 
-    Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+    Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
     EclDirectWUExceptions errors(*cw);
     resp.setErrors(errors);
 

+ 1 - 1
esp/services/ws_dfu/ws_dfuService.cpp

@@ -1592,7 +1592,7 @@ bool CWsDfuEx::checkFileContent(IEspContext &context, IUserDescriptor* udesc, co
                 Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
                 if (factory)
                 {
-                    IConstWorkUnit* wu = factory->openWorkUnit(wuid, false, context.querySecManager(), context.queryUser());
+                    IConstWorkUnit* wu = factory->openWorkUnit(wuid, context.querySecManager(), context.queryUser());
                     if (wu)
                         eclCluster.set(wu->queryClusterName());
                 }

+ 1 - 1
esp/services/ws_ecl/ws_ecl_wuinfo.cpp

@@ -37,7 +37,7 @@ IConstWorkUnit *WsEclWuInfo::ensureWorkUnit()
     if (wu)
         return wu;
     Owned<IWorkUnitFactory> wf = getWorkUnitFactory();
-    wu.setown(wf->openWorkUnit(wuid.str(), false));
+    wu.setown(wf->openWorkUnit(wuid.str()));
     if (!wu)
         throw MakeStringException(-1, "Could not open workunit: %s", wuid.str());
     if (isLibrary(wu))

+ 1 - 1
esp/services/ws_smc/ws_smcService.cpp

@@ -526,7 +526,7 @@ CWsSMCTargetCluster* CActivityInfo::findWUClusterInfo(const char* wuid, bool isO
     try
     {
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid);
         if (!cw)
             return NULL;
         clusterName.set(cw->queryClusterName());

+ 2 - 2
esp/services/ws_workunits/WUWrapper.hpp

@@ -32,13 +32,13 @@ class CWUWrapper : public CInterface
 public:
     CWUWrapper() {}
     CWUWrapper(const char* wuid, IEspContext &context): 
-        factory(getWorkUnitFactory()), wu(factory->openWorkUnit(wuid, false, context.querySecManager(), context.queryUser()))
+        factory(getWorkUnitFactory()), wu(factory->openWorkUnit(wuid, context.querySecManager(), context.queryUser()))
     {
         if(!wu)
             throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Could not open workunit %s",wuid);
     }
 
-    CWUWrapper(const char* wuid): factory(getWorkUnitFactory()), wu(factory->openWorkUnit(wuid, false))
+    CWUWrapper(const char* wuid): factory(getWorkUnitFactory()), wu(factory->openWorkUnit(wuid))
     {
         if(!wu)
             throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Could not open workunit %s",wuid);

+ 3 - 3
esp/services/ws_workunits/ws_workunitsHelpers.cpp

@@ -94,7 +94,7 @@ void ensureWsWorkunitAccess(IEspContext& cxt, IConstWorkUnit& cw, SecAccessFlags
 void ensureWsWorkunitAccess(IEspContext& context, const char* wuid, SecAccessFlags minAccess)
 {
     Owned<IWorkUnitFactory> wf = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-    Owned<IConstWorkUnit> cw = wf->openWorkUnit(wuid, false);
+    Owned<IConstWorkUnit> cw = wf->openWorkUnit(wuid);
     if (!cw)
         throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT, "Failed to open workunit %s when ensuring workunit access", wuid);
     ensureWsWorkunitAccess(context, *cw, minAccess);
@@ -3078,7 +3078,7 @@ void WsWuHelpers::submitWsWorkunit(IEspContext& context, const char *wuid, const
     const char *paramXml, IArrayOf<IConstNamedValue> *variables, IArrayOf<IConstNamedValue> *debugs)
 {
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-    Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
+    Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid);
     if(!cw)
         throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot open workunit %s.",wuid);
     return submitWsWorkunit(context, cw, cluster, snapshot, maxruntime, compile, resetWorkflow, resetVariables, paramXml, variables, debugs);
@@ -3088,7 +3088,7 @@ void WsWuHelpers::submitWsWorkunit(IEspContext& context, const char *wuid, const
 void WsWuHelpers::copyWsWorkunit(IEspContext &context, IWorkUnit &wu, const char *srcWuid)
 {
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-    Owned<IConstWorkUnit> src(factory->openWorkUnit(srcWuid, false));
+    Owned<IConstWorkUnit> src(factory->openWorkUnit(srcWuid));
 
     queryExtendedWU(&wu)->copyWorkUnit(src, false);
 

+ 1 - 1
esp/services/ws_workunits/ws_workunitsHelpers.hpp

@@ -146,7 +146,7 @@ public:
         wuid.set(wuid_);
         version = context.getClientVersion();
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(ctx.querySecManager(), ctx.queryUser());
-        cw.setown(factory->openWorkUnit(wuid_, false));
+        cw.setown(factory->openWorkUnit(wuid_));
         if(!cw)
             throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot open workunit %s.", wuid_);
     }

+ 5 - 5
esp/services/ws_workunits/ws_workunitsQuerySets.cpp

@@ -348,7 +348,7 @@ void QueryFilesInUse::loadTarget(IPropertyTree *t, const char *target, unsigned
         }
 
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid);
         if (!cw)
             continue;
 
@@ -441,7 +441,7 @@ bool CWsWorkunitsEx::onWUCopyLogicalFiles(IEspContext &context, IEspWUCopyLogica
     WsWuHelpers::checkAndTrimWorkunit("WUCopyLogicalFiles", wuid);
 
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-    Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+    Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
     if (!cw)
         throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot open workunit %s", wuid.str());
 
@@ -744,7 +744,7 @@ bool CWsWorkunitsEx::onWUPublishWorkunit(IEspContext &context, IEspWUPublishWork
     WsWuHelpers::checkAndTrimWorkunit("WUPublishWorkunit", wuid);
 
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-    Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+    Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
     if (!cw)
         throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot find the workunit %s", wuid.str());
 
@@ -1552,7 +1552,7 @@ bool CWsWorkunitsEx::onWUQueryDetails(IEspContext &context, IEspWUQueryDetailsRe
     if (version >= 1.46)
     {
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid);
         if(!cw)
             throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot open workunit %s.",wuid);
 
@@ -2389,7 +2389,7 @@ bool CWsWorkunitsEx::onWUQuerysetCopyQuery(IEspContext &context, IEspWUQuerySetC
     }
 
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-    Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+    Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
 
     if (!req.getDontCopyFiles())
     {

+ 28 - 28
esp/services/ws_workunits/ws_workunitsService.cpp

@@ -226,7 +226,7 @@ bool doAction(IEspContext& context, StringArray& wuids, int action, IProperties*
             else
             {
                 Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-                Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
+                Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid);
                 if(!cw)
                     throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot open workunit %s.",wuid);
 
@@ -373,7 +373,7 @@ static void checkUpdateQuerysetLibraries()
             const char *wuid = query.queryProp("@wuid");
             if (!wuid || !*wuid)
                 continue;
-            Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
+            Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid);
             if (!cw)
                 continue;
             checkAddLibrariesToQueryEntry(&query, cw);
@@ -547,14 +547,14 @@ bool CWsWorkunitsEx::onWUUpdate(IEspContext &context, IEspWUUpdateRequest &req,
         ensureWsWorkunitAccess(context, wuid.str(), SecAccess_Write);
 
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
         if(!cw)
             throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot open workunit %s.",wuid.str());
         if(req.getProtected() != req.getProtectedOrig())
         {
             cw->protect(req.getProtected());
             cw.clear();
-            cw.setown(factory->openWorkUnit(wuid.str(), false));
+            cw.setown(factory->openWorkUnit(wuid.str()));
             if(!cw)
                 throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot open workunit %s.",wuid.str());
         }
@@ -848,7 +848,7 @@ bool CWsWorkunitsEx::onWUResubmit(IEspContext &context, IEspWUResubmitRequest &r
                 Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
                 if(req.getCloneWorkunit() || req.getRecompile())
                 {
-                    Owned<IConstWorkUnit> src(factory->openWorkUnit(wuid.str(), false));
+                    Owned<IConstWorkUnit> src(factory->openWorkUnit(wuid.str()));
                     NewWsWorkunit wu(factory, context);
                     wuid.set(wu->queryWuid());
                     queryExtendedWU(wu)->copyWorkUnit(src, false);
@@ -859,7 +859,7 @@ bool CWsWorkunitsEx::onWUResubmit(IEspContext &context, IEspWUResubmitRequest &r
 
                 wuids.append(wuid.str());
 
-                Owned<IConstWorkUnit> cw(factory->openWorkUnit(wuid.str(), false));
+                Owned<IConstWorkUnit> cw(factory->openWorkUnit(wuid.str()));
                 if(!cw)
                     throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot open workunit %s.",wuid.str());
 
@@ -1007,7 +1007,7 @@ bool CWsWorkunitsEx::onWUSubmit(IEspContext &context, IEspWUSubmitRequest &req,
             throw MakeStringException(ECLWATCH_INVALID_CLUSTER_NAME, "Invalid cluster name: %s", cluster);
 
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
         if(!cw)
             throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot open workunit %s.",wuid.str());
 
@@ -1091,7 +1091,7 @@ bool CWsWorkunitsEx::onWURun(IEspContext &context, IEspWURunRequest &req, IEspWU
             waitForWorkUnitToComplete(wuid.str(), timeToWait);
 
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
         if (!cw)
             throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot open workunit %s.", wuid.str());
 
@@ -1132,7 +1132,7 @@ bool CWsWorkunitsEx::onWUWaitCompiled(IEspContext &context, IEspWUWaitRequest &r
         WsWuHelpers::checkAndTrimWorkunit("WUWaitCompiled", wuid);
         secWaitForWorkUnitToCompile(wuid.str(), *context.querySecManager(), *context.queryUser(), req.getWait());
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
         if(!cw)
             throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot open workunit %s.",wuid.str());
         resp.setStateID(cw->getState());
@@ -1205,7 +1205,7 @@ bool CWsWorkunitsEx::onWUSyntaxCheckECL(IEspContext &context, IEspWUSyntaxCheckR
         WsWuHelpers::submitWsWorkunit(context, wuid.str(), req.getCluster(), req.getSnapshot(), 0, true, false, false);
         waitForWorkUnitToComplete(wuid.str(), req.getTimeToWait());
 
-        Owned<IConstWorkUnit> cw(factory->openWorkUnit(wuid.str(), false));
+        Owned<IConstWorkUnit> cw(factory->openWorkUnit(wuid.str()));
         WsWUExceptions errors(*cw);
         resp.setErrors(errors);
         cw.clear();
@@ -1253,7 +1253,7 @@ bool CWsWorkunitsEx::onWUCompileECL(IEspContext &context, IEspWUCompileECLReques
         WsWuHelpers::submitWsWorkunit(context, wuid.str(), req.getCluster(), req.getSnapshot(), 0, true, false, false);
         waitForWorkUnitToComplete(wuid.str(),req.getTimeToWait());
 
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
 
         SCMStringBuffer s;
         cw->getDebugValue("__Calculated__Complexity__",s);
@@ -1350,7 +1350,7 @@ bool CWsWorkunitsEx::onWUGetDependancyTrees(IEspContext& context, IEspWUGetDepen
         WsWuHelpers::submitWsWorkunit(context, wuid.str(), req.getCluster(), req.getSnapshot(), 0, true, false, false);
 
         int state = waitForWorkUnitToComplete(wuid.str(), timeMilliSec);
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
 
         WsWUExceptions errors(*cw);
         resp.setErrors(errors);
@@ -1615,7 +1615,7 @@ void doWUQueryByFile(IEspContext &context, const char *logicalFile, IEspWUQueryR
         throw MakeStringException(ECLWATCH_CANNOT_GET_WORKUNIT,"Cannot find the workunit for file %s.", logicalFile);
 
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-    Owned<IConstWorkUnit> cw= factory->openWorkUnit(wuid.str(), false);
+    Owned<IConstWorkUnit> cw= factory->openWorkUnit(wuid.str());
     if (!cw)
         throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot find the workunit for file %s.", logicalFile);
     if (getWsWorkunitAccess(context, *cw) < SecAccess_Read)
@@ -2290,7 +2290,7 @@ void getWsWuResult(IEspContext &context, const char* wuid, const char *name, con
     WUState& wuState, bool xsd=true)
 {
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-    Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
+    Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid);
     if(!cw)
         throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot open workunit %s.",wuid);
     Owned<IConstWUResult> result;
@@ -2698,7 +2698,7 @@ bool CWsWorkunitsEx::onWUResultSummary(IEspContext &context, IEspWUResultSummary
         WsWuHelpers::checkAndTrimWorkunit("WUResultSummary", wuid);
 
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
         if(!cw)
             throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot open workunit %s.",wuid.str());
         ensureWsWorkunitAccess(context, *cw, SecAccess_Read);
@@ -2744,7 +2744,7 @@ void getWorkunitCluster(IEspContext &context, const char* wuid, SCMStringBuffer&
         return;
 
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-    Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
+    Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid);
     if (cw)
         cluster.set(cw->queryClusterName());
     else if (checkArchiveWUs)
@@ -2851,7 +2851,7 @@ bool CWsWorkunitsEx::onWUResult(IEspContext &context, IEspWUResultRequest &req,
                     throw MakeStringException(ECLWATCH_INVALID_INPUT,"Need valid target cluster to browse file %s.",logicalName);
 
                 Owned<IWorkUnitFactory> wf = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-                Owned<IConstWorkUnit> cw = wf->openWorkUnit(lwuid.str(), false);
+                Owned<IConstWorkUnit> cw = wf->openWorkUnit(lwuid.str());
                 if (cw)
                     wuState = cw->getState();
             }
@@ -2930,7 +2930,7 @@ void getScheduledWUs(IEspContext &context, const char *stateReq, const char *ser
                         SCMStringBuffer state;
                         try
                         {
-                            Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+                            Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
                             if (!cw && (!stateReq || !*stateReq))
                             	match = true;
                             else if (cw)
@@ -3074,7 +3074,7 @@ bool CWsWorkunitsEx::onWUExport(IEspContext &context, IEspWUExportRequest &req,
         StringBuffer xml("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Workunits>");
         for(WsWuSearch::iterator it=ws.begin(); it!=ws.end(); it++)
         {
-            Owned<IConstWorkUnit> cw = factory->openWorkUnit(it->c_str(), false);
+            Owned<IConstWorkUnit> cw = factory->openWorkUnit(it->c_str());
             if (cw)
                 exportWorkUnitToXML(cw, xml, true, false, true);
         }
@@ -3102,7 +3102,7 @@ bool CWsWorkunitsEx::onWUListLocalFileRequired(IEspContext& context, IEspWUListL
         ensureWsWorkunitAccess(context, wuid.str(), SecAccess_Read);
 
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
         if (!cw)
             throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT, "Workunit %s not found.", wuid.str());
 
@@ -3321,7 +3321,7 @@ bool CWsWorkunitsEx::onWUProcessGraph(IEspContext &context,IEspWUProcessGraphReq
         WsWuHelpers::checkAndTrimWorkunit("WUProcessGraph", wuid);
 
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
         if(!cw)
             throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot open workunit %s.",wuid.str());
         ensureWsWorkunitAccess(context, *cw, SecAccess_Read);
@@ -3410,7 +3410,7 @@ bool CWsWorkunitsEx::onWUGetGraph(IEspContext& context, IEspWUGetGraphRequest& r
         WsWuHelpers::checkAndTrimWorkunit("WUGetGraph", wuid);
 
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
         if(!cw)
             throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot open workunit %s.",wuid.str());
         ensureWsWorkunitAccess(context, *cw, SecAccess_Read);
@@ -3469,7 +3469,7 @@ bool CWsWorkunitsEx::onWUGraphInfo(IEspContext &context,IEspWUGraphInfoRequest &
         WsWuHelpers::checkAndTrimWorkunit("WUGraphInfo", wuid);
 
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
         if(!cw)
             throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot open workunit %s.",wuid.str());
 
@@ -3498,7 +3498,7 @@ bool CWsWorkunitsEx::onWUGVCGraphInfo(IEspContext &context,IEspWUGVCGraphInfoReq
         WsWuHelpers::checkAndTrimWorkunit("WUGVCGraphInfo", wuid);
 
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
         if(!cw)
             throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot open workunit %s.",wuid.str());
 
@@ -3538,7 +3538,7 @@ bool CWsWorkunitsEx::onWUGraphTiming(IEspContext &context, IEspWUGraphTimingRequ
         WsWuHelpers::checkAndTrimWorkunit("WUGraphTiming", wuid);
 
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str(), false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid.str());
         if(!cw)
             throw MakeStringException(ECLWATCH_CANNOT_UPDATE_WORKUNIT,"Cannot open workunit %s.",wuid.str());
         ensureWsWorkunitAccess(context, *cw, SecAccess_Read);
@@ -3768,7 +3768,7 @@ void deploySharedObject(IEspContext &context, StringBuffer &wuid, const char *fi
             if (crc)
             {
                 Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-                Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
+                Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid);
                 if (cw)
                 {
                     //is this a previous copy of same query, or a WUID collision?
@@ -4056,7 +4056,7 @@ bool CWsWorkunitsEx::onWUCreateZAPInfo(IEspContext &context, IEspWUCreateZAPInfo
     try
     {
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-        Owned<IConstWorkUnit> cwu = factory->openWorkUnit(req.getWuid(), false);
+        Owned<IConstWorkUnit> cwu = factory->openWorkUnit(req.getWuid());
         if(!cwu.get())
             throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT, "Cannot open workunit %s.", req.getWuid());
 
@@ -4133,7 +4133,7 @@ bool CWsWorkunitsEx::onWUGetZAPInfo(IEspContext &context, IEspWUGetZAPInfoReques
         WsWuHelpers::checkAndTrimWorkunit("WUGetZAPInfo", wuid);
 
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory(context.querySecManager(), context.queryUser());
-        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid, false);
+        Owned<IConstWorkUnit> cw = factory->openWorkUnit(wuid);
         if(!cw)
             throw MakeStringException(ECLWATCH_CANNOT_OPEN_WORKUNIT,"Cannot open workunit %s.",wuid.str());
 

+ 1 - 1
esp/smc/SMCLib/WUXMLInfo.cpp

@@ -113,7 +113,7 @@ bool CWUXMLInfo::buildXmlWuidInfo(const char* wuid, IEspECLWorkunit& wuStructure
 {
     try{
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-        Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid, false);
+        Owned<IConstWorkUnit> wu = factory->openWorkUnit(wuid);
         if (wu)
         {
             return buildXmlWuidInfo(*wu.get(),wuStructure,bDescription);

+ 74 - 70
plugins/cassandra/cassandrawu.cpp

@@ -33,7 +33,9 @@
 #include "jptree.hpp"
 #include "jregexp.hpp"
 #include "dadfs.hpp"
+#include "dasds.hpp"
 
+#include "wuerror.hpp"
 #include "workunit.hpp"
 #include "workunit.ipp"
 
@@ -52,6 +54,7 @@ namespace cassandraembed {
 #define CASS_SEARCH_PREFIX_SIZE 2
 #define NUM_PARTITIONS 2
 
+
 static const CassValue *getSingleResult(const CassResult *result)
 {
     const CassRow *row = cass_result_first_row(result);
@@ -908,8 +911,8 @@ static const CassandraXmlMapping workunitsMappings [] =
     {"action", "text", "Action", stringColumnMapper},
     {"protected", "boolean", "@protected", boolColumnMapper},
     {"scheduled", "text", "@timeScheduled", stringColumnMapper},   // Should store as a date?
-    {"totalThorTime", "text", "@totalThorTime", stringColumnMapper},  // We store in the wu ptree as a collatable string. Need to force to one partition too
-    {"appvalues", "map<text, text>", "@Application@", subTreeMapColumnMapper}, // MORE - change to a custom map to make searchable
+    {"totalThorTime", "text", "@totalThorTime", stringColumnMapper},  // We store in the wu ptree as a collatable string (with leading spaces to force to one partition)
+    {"appvalues", "map<text, text>", "@Application@", subTreeMapColumnMapper},
 
     {"debug", "map<text, text>", "Debug", simpleMapColumnMapper},
     {"attributes", "map<text, text>", "@wuid@clusterName@jobName@priorityClass@protected@scope@submitID@state@timeScheduled@totalThorTime@", attributeMapColumnMapper},  // name is the suppression list, note trailing @
@@ -1134,7 +1137,7 @@ static const CassandraXmlMapping wuFilesReadMappings [] =
     {"wuid", "text", NULL, rootNameColumnMapper},
     {"name", "text", "@name", stringColumnMapper},
     {"cluster", "text", "@cluster", stringColumnMapper},
-    {"useCount", "int", "@useCount", intColumnMapper}, // MORE - could think about using a counter column, but would mess up the commit paradigm
+    {"useCount", "int", "@useCount", intColumnMapper}, // NOTE - could think about using a counter column, but would mess up the commit paradigm
     {"subfiles", "list<text>", NULL, subfileListColumnMapper},
     { NULL, "wuFilesRead", "((partition, wuid), name)", stringColumnMapper}
 };
@@ -1157,6 +1160,7 @@ interface ICassandraSession : public IInterface  // MORE - rename!
 
     virtual const CassResult *fetchDataForWuid(const CassandraXmlMapping *mappings, const char *wuid, bool includeWuid) const = 0;
     virtual void deleteChildByWuid(const CassandraXmlMapping *mappings, const char *wuid, CassBatch *batch) const = 0;
+    virtual IPTree *cassandraToWorkunitXML(const char *wuid) const = 0;
 };
 
 void getBoundFieldNames(const CassandraXmlMapping *mappings, StringBuffer &names, StringBuffer &bindings, IPTree *inXML, const char *userVal, StringBuffer &tableName)
@@ -2126,21 +2130,29 @@ private:
     bool descending;
 };
 
-class CCassandraWorkUnit : public CLocalWorkUnit
+static void lockWuid(Owned<IRemoteConnection> &connection, const char *wuid)
+{
+    VStringBuffer wuRoot("/WorkUnitLocks/%s", wuid);
+    if (connection)
+        connection->changeMode(RTM_LOCK_WRITE|RTM_CREATE_QUERY, SDS_LOCK_TIMEOUT); // Would it ever be anything else?
+    else
+        connection.setown(querySDS().connect(wuRoot.str(), myProcessSession(), RTM_LOCK_WRITE|RTM_CREATE_QUERY, SDS_LOCK_TIMEOUT));
+    if (!connection)
+        throw MakeStringException(WUERR_LockFailed, "Failed to get connection for xpath %s", wuRoot.str());
+}
+
+class CCassandraWorkUnit : public CPersistedWorkUnit
 {
-    // IMPLEMENT_IINTERFACE;
 public:
     IMPLEMENT_IINTERFACE;
-    CCassandraWorkUnit(ICassandraSession *_sessionCache, IPTree *wuXML, ISecManager *secmgr, ISecUser *secuser, bool write)
-        : sessionCache(_sessionCache), CLocalWorkUnit(secmgr, secuser)
+    CCassandraWorkUnit(ICassandraSession *_sessionCache, IPTree *wuXML, ISecManager *secmgr, ISecUser *secuser,  IRemoteConnection *_daliLock)
+        : sessionCache(_sessionCache), CPersistedWorkUnit(secmgr, secuser), daliLock(_daliLock)
     {
-        CLocalWorkUnit::loadPTree(wuXML);
+        CPersistedWorkUnit::loadPTree(wuXML);
         allDirty = false;   // Debatable... depends where the XML came from! If we read it from Cassandra. it's not. Otherwise, it is...
         memset(childLoaded, 0, sizeof(childLoaded));
-        abortDirty = true;
-        abortState = false;
-        if (write)
-            _lockRemote();
+        if (daliLock)
+            createBatch();
     }
     ~CCassandraWorkUnit()
     {
@@ -2148,15 +2160,17 @@ public:
 
     virtual void forceReload()
     {
-        printStackReport();
-        UNIMPLEMENTED;
+        synchronized sync(locked); // protect locked workunits (uncommited writes) from reload
+        loadPTree(sessionCache->cassandraToWorkunitXML(queryWuid()));
+        memset(childLoaded, 0, sizeof(childLoaded));
+        allDirty = false;
         abortDirty = true;
     }
 
     virtual void cleanupAndDelete(bool deldll, bool deleteOwned, const StringArray *deleteExclusions)
     {
         const char *wuid = queryWuid();
-        CLocalWorkUnit::cleanupAndDelete(deldll, deleteOwned, deleteExclusions);
+        CPersistedWorkUnit::cleanupAndDelete(deldll, deleteOwned, deleteExclusions);
         if (!batch)
             batch.setown(new CassandraBatch(cass_batch_new(CASS_BATCH_TYPE_UNLOGGED)));
         deleteChildren(wuid);
@@ -2172,7 +2186,7 @@ public:
 
     virtual void commit()
     {
-        CLocalWorkUnit::commit();
+        CPersistedWorkUnit::commit();
         if (sessionCache->queryTraceLevel() >= 8)
         {
             StringBuffer s; toXML(p, s); DBGLOG("CCassandraWorkUnit::commit\n%s", s.str());
@@ -2255,82 +2269,66 @@ public:
     virtual void setUser(const char *user)
     {
         if (trackSecondaryChange(user, "@submitID"))
-            CLocalWorkUnit::setUser(user);
+            CPersistedWorkUnit::setUser(user);
     }
     virtual void setClusterName(const char *cluster)
     {
         if (trackSecondaryChange(cluster, "@clusterName"))
-            CLocalWorkUnit::setClusterName(cluster);
+            CPersistedWorkUnit::setClusterName(cluster);
     }
     virtual void setJobName(const char *jobname)
     {
         if (trackSecondaryChange(jobname, "@jobName"))
-            CLocalWorkUnit::setJobName(jobname);
+            CPersistedWorkUnit::setJobName(jobname);
     }
     virtual void setState(WUState state)
     {
         if (trackSecondaryChange(getWorkunitStateStr(state), "@state"))
-            CLocalWorkUnit::setState(state);
+            CPersistedWorkUnit::setState(state);
     }
     virtual void setApplicationValue(const char *app, const char *propname, const char *value, bool overwrite)
     {
         VStringBuffer xpath("Application/%s/%s", app, propname);
         if (trackSecondaryChange(value, xpath))
-            CLocalWorkUnit::setApplicationValue(app, propname, value, overwrite);
+            CPersistedWorkUnit::setApplicationValue(app, propname, value, overwrite);
     }
 
     virtual void _lockRemote()
     {
-        batch.setown(new CassandraBatch(cass_batch_new(CASS_BATCH_TYPE_UNLOGGED)));
+        lockWuid(daliLock, queryWuid());
+        createBatch();
     }
 
     virtual void _unlockRemote()
     {
-//        printStackReport();
-//        UNIMPLEMENTED;
         commit();
         batch.clear();
-    }
-
-    virtual void subscribe(WUSubscribeOptions options)
-    {
-//        printStackReport();
-//        UNIMPLEMENTED;
-    }
-
-    virtual void unsubscribe()
-    {
-//        printStackReport();
-//        UNIMPLEMENTED;
-    }
-
-    virtual bool aborting() const
-    {
-        return false;
-        // MORE - work out what to do about aborts in Cassandra
-//        printStackReport();
-//        UNIMPLEMENTED;
+        if (daliLock)
+        {
+            daliLock->close(true);
+            daliLock.clear();
+        }
     }
 
     virtual IWUResult * updateResultByName(const char * name)
     {
-        return noteDirty(CLocalWorkUnit::updateResultByName(name));
+        return noteDirty(CPersistedWorkUnit::updateResultByName(name));
     }
     virtual IWUResult * updateResultBySequence(unsigned seq)
     {
-        return noteDirty(CLocalWorkUnit::updateResultBySequence(seq));
+        return noteDirty(CPersistedWorkUnit::updateResultBySequence(seq));
     }
     virtual IWUResult * updateTemporaryByName(const char * name)
     {
-        return noteDirty(CLocalWorkUnit::updateTemporaryByName(name));
+        return noteDirty(CPersistedWorkUnit::updateTemporaryByName(name));
     }
     virtual IWUResult * updateVariableByName(const char * name)
     {
-        return noteDirty(CLocalWorkUnit::updateVariableByName(name));
+        return noteDirty(CPersistedWorkUnit::updateVariableByName(name));
     }
     virtual IWUException *createException()
     {
-        IWUException *result = CLocalWorkUnit::createException();
+        IWUException *result = CPersistedWorkUnit::createException();
         VStringBuffer xpath("Exceptions/Exception[@sequence='%d']", result->getSequence());
         noteDirty(xpath, wuExceptionsMappings);
         return result;
@@ -2343,7 +2341,7 @@ public:
             trackSecondaryChange(fromP->queryProp(*search), *search);
         for (const ChildTableInfo * const * table = childTables; *table != NULL; table++)
             checkChildLoaded(**table);
-        CLocalWorkUnit::copyWorkUnit(cached, all);
+        CPersistedWorkUnit::copyWorkUnit(cached, all);
         memset(childLoaded, 1, sizeof(childLoaded));
         allDirty = true;
     }
@@ -2351,7 +2349,7 @@ public:
     {
         if (file)
         {
-            CLocalWorkUnit::noteFileRead(file);
+            CPersistedWorkUnit::noteFileRead(file);
             VStringBuffer xpath("FilesRead/File[@name='%s']", file->queryLogicalName());
             noteDirty(xpath, wuFilesReadMappings);
         }
@@ -2370,44 +2368,44 @@ public:
     virtual void _loadFilesRead() const
     {
         checkChildLoaded(wuFilesReadTable);        // Lazy populate the FilesRead branch of p from Cassandra
-        CLocalWorkUnit::_loadFilesRead();
+        CPersistedWorkUnit::_loadFilesRead();
     }
 
     virtual void _loadResults() const
     {
         checkChildLoaded(wuResultsTable);        // Lazy populate the Results branch of p from Cassandra
-        CLocalWorkUnit::_loadResults();
+        CPersistedWorkUnit::_loadResults();
     }
 
     virtual void _loadVariables() const
     {
         checkChildLoaded(wuVariablesTable);        // Lazy populate the Variables branch of p from Cassandra
-        CLocalWorkUnit::_loadVariables();
+        CPersistedWorkUnit::_loadVariables();
     }
 
     virtual void _loadTemporaries() const
     {
         checkChildLoaded(wuTemporariesTable);        // Lazy populate the Temporaries branch of p from Cassandra
-        CLocalWorkUnit::_loadTemporaries();
+        CPersistedWorkUnit::_loadTemporaries();
     }
 
     virtual void _loadStatistics() const
     {
         checkChildLoaded(wuStatisticsTable);        // Lazy populate the Statistics branch of p from Cassandra
-        CLocalWorkUnit::_loadStatistics();
+        CPersistedWorkUnit::_loadStatistics();
     }
 
     virtual void _loadExceptions() const
     {
         checkChildLoaded(wuExceptionsTable);        // Lazy populate the Exceptions branch of p from Cassandra
-        CLocalWorkUnit::_loadExceptions();
+        CPersistedWorkUnit::_loadExceptions();
     }
 
     virtual void clearExceptions()
     {
         CriticalBlock b(crit);
         noteDirty("*Exceptions/Exception", wuExceptionsMappings);
-        CLocalWorkUnit::clearExceptions();
+        CPersistedWorkUnit::clearExceptions();
     }
 
     virtual IPropertyTree *queryPTree() const
@@ -2419,6 +2417,10 @@ public:
         return p;
     }
 protected:
+    void createBatch()
+    {
+        batch.setown(new CassandraBatch(cass_batch_new(CASS_BATCH_TYPE_UNLOGGED)));
+    }
     // Delete child table rows
     void deleteChildren(const char *wuid)
     {
@@ -2584,8 +2586,6 @@ protected:
         dirtyPaths.setValue(xpath, table);
     }
     Linked<const ICassandraSession> sessionCache;
-    mutable bool abortDirty;
-    mutable bool abortState;
     mutable bool childLoaded[ChildTablesSize];
     bool allDirty;
     Owned<IPTree> prev;
@@ -2593,6 +2593,7 @@ protected:
     Owned<CassandraBatch> batch;
     MapStringTo<const CassandraXmlMapping *> dirtyPaths;
     IArrayOf<IWUResult> dirtyResults;
+    Owned<IRemoteConnection> daliLock;  // We still use dali for locking
 };
 
 class CCasssandraWorkUnitFactory : public CWorkUnitFactory, implements ICassandraSession
@@ -2678,7 +2679,9 @@ public:
                 // If there are multiple columns it will be '[applied]' (value false) and the fields of the existing row
                 Owned<IPTree> wuXML = createPTree(useWuid);
                 wuXML->setProp("@xmlns:xsi", "http://www.w3.org/1999/XMLSchema-instance");
-                Owned<CLocalWorkUnit> wu = new CCassandraWorkUnit(this, wuXML.getClear(), secmgr, secuser, true);
+                Owned<IRemoteConnection> daliLock;
+                lockWuid(daliLock, useWuid);
+                Owned<CLocalWorkUnit> wu = new CCassandraWorkUnit(this, wuXML.getClear(), secmgr, secuser, daliLock.getClear());
                 return wu.getClear();
             }
             suffix = rand_r(&randState);
@@ -2686,18 +2689,21 @@ public:
                 suffixLength++;
         }
     }
-    virtual CLocalWorkUnit* _openWorkUnit(const char *wuid, bool lock, ISecManager *secmgr, ISecUser *secuser)
+    virtual CLocalWorkUnit* _openWorkUnit(const char *wuid, ISecManager *secmgr, ISecUser *secuser)
     {
         Owned<IPTree> wuXML = cassandraToWorkunitXML(wuid);
         if (wuXML)
-            return new CCassandraWorkUnit(this, wuXML.getClear(), secmgr, secuser, lock);
+            return new CCassandraWorkUnit(this, wuXML.getClear(), secmgr, secuser, NULL);
         else
             return NULL;
     }
     virtual CLocalWorkUnit* _updateWorkUnit(const char *wuid, ISecManager *secmgr, ISecUser *secuser)
     {
+        // We still use dali for the locks
+        Owned<IRemoteConnection> daliLock;
+        lockWuid(daliLock, wuid);
         Owned<IPTree> wuXML = cassandraToWorkunitXML(wuid);
-        Owned<CLocalWorkUnit> wu = new CCassandraWorkUnit(this, wuXML.getClear(), secmgr, secuser, true);
+        Owned<CLocalWorkUnit> wu = new CCassandraWorkUnit(this, wuXML.getClear(), secmgr, secuser, daliLock.getClear());
         return wu.getClear();
     }
 
@@ -2772,7 +2778,7 @@ public:
         bool sortDescending = (sortorder & WUSFreverse) || needsPostSort;
         if (!result)
         {
-            Owned<CassMultiIterator> merger = new CassMultiIterator(needsPostSort ? NULL : cached, 0, 0, sortDescending); // We always merge by wuid // MORE - except when we merge by thor time....
+            Owned<CassMultiIterator> merger = new CassMultiIterator(needsPostSort ? NULL : cached, 0, 0, sortDescending); // We always merge by wuid (except when we merge by thor time... we turn the compare off then to make it an appender)
             if (startOffset)
             {
                 StringBuffer startWuid;
@@ -2934,7 +2940,7 @@ public:
             {
                 merger->addPostFilters(remoteWildFilters, 1);  // Any other filters have to be done locally
                 // Convert into a value IN [] which we do via a merge
-                // MORE - If we want sorted by filter (or don't care about sort order), we could do directly as a range - but the wuid range filters then don't work, and the merger would be invalid
+                // NOTE - If we want sorted by filter (or don't care about sort order), we could do directly as a range - but the wuid range filters then don't work, and the merger would be invalid
                 StringArray fieldValues;
                 const IPostFilter &best= remoteWildFilters.item(0);
                 _getUniqueValues(best.queryXPath(), best.queryValue(), fieldValues);
@@ -2988,10 +2994,8 @@ public:
         return getUnsignedResult(NULL, getSingleResult(result));
     }
     /*
-    virtual void descheduleAllWorkUnits(ISecManager *secmgr, ISecUser *secuser) { UNIMPLEMENTED; }
-    virtual IConstQuerySetQueryIterator * getQuerySetQueriesSorted(WUQuerySortField *sortorder, WUQuerySortField *filters, const void *filterbuf, unsigned startoffset, unsigned maxnum, __int64 *cachehint, unsigned *total, const MapStringTo<bool> *subset) { UNIMPLEMENTED; }
-    virtual bool isAborting(const char *wuid) const { UNIMPLEMENTED; }
-    virtual void clearAborting(const char *wuid) { UNIMPLEMENTED; }
+    virtual bool isAborting(const char *wuid) const - done in the base class using dali
+    virtual void clearAborting(const char *wuid) - done in the base class using dali
     */
     virtual WUState waitForWorkUnit(const char * wuid, unsigned timeout, bool compiled, bool returnOnWaitState)
     {

+ 1 - 1
plugins/fileservices/fileservices.cpp

@@ -167,7 +167,7 @@ static IConstWorkUnit * getWorkunit(ICodeContext * ctx)
     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
     StringAttr wuid;
     wuid.setown(ctx->getWuid());
-    return factory->openWorkUnit(wuid, false);
+    return factory->openWorkUnit(wuid);
 }
 
 static IConstEnvironment * openDaliEnvironment()

+ 1 - 1
plugins/workunitservices/workunitservices.cpp

@@ -219,7 +219,7 @@ static IWorkUnitFactory * getWorkunitFactory(ICodeContext * ctx)
 static IConstWorkUnit * getWorkunit(ICodeContext * ctx, const char * wuid)
 {
     Owned<IWorkUnitFactory> wuFactory = getWorkunitFactory(ctx);
-    return wuFactory->openWorkUnit(wuid, false);
+    return wuFactory->openWorkUnit(wuid);
 }
 
 static IConstWorkUnit * getWorkunit(ICodeContext * ctx)

+ 1 - 1
roxie/ccd/ccdcontext.cpp

@@ -1976,7 +1976,7 @@ protected:
                 if (daliHelper && daliHelper->connected())
                 {
                     Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-                    Owned<IConstWorkUnit> externalWU = factory->openWorkUnit(wuid, false);
+                    Owned<IConstWorkUnit> externalWU = factory->openWorkUnit(wuid);
                     externalWU->remoteCheckAccess(queryUserDescriptor(), false);
                     Owned<IConstWUResult> wuResult = getWorkUnitResult(externalWU, stepname, sequence);
                     if (!wuResult)

+ 1 - 1
roxie/ccd/ccddali.cpp

@@ -613,7 +613,7 @@ public:
         }
         w->commit();
         w.clear();
-        return wuFactory->openWorkUnit(wuid, false);
+        return wuFactory->openWorkUnit(wuid);
     }
 
     virtual void noteWorkunitRunning(const char *wuid, bool running)

+ 1 - 1
thorlcr/graph/thgraphmaster.cpp

@@ -1217,7 +1217,7 @@ public:
     virtual IConstWUResult *getExternalResult(const char * wuid, const char *name, unsigned sequence)
     {
         Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-        Owned<IConstWorkUnit> externalWU = factory->openWorkUnit(wuid, false);
+        Owned<IConstWorkUnit> externalWU = factory->openWorkUnit(wuid);
         externalWU->remoteCheckAccess(userDesc, false);
         return getWorkUnitResult(externalWU, name, sequence);
     }

+ 2 - 2
thorlcr/master/thgraphmanager.cpp

@@ -214,7 +214,7 @@ static int getRunningMaxPriority(const char *qname)
                             const char* wuid=wu.queryProp(NULL);
                             if (wuid&&*wuid) {
                                 Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
-                                Owned<IConstWorkUnit> workunit = factory->openWorkUnit(wuid, false);
+                                Owned<IConstWorkUnit> workunit = factory->openWorkUnit(wuid);
                                 if (workunit) {
                                     int priority = workunit->getPriorityValue();
                                     if (priority>maxpriority)
@@ -496,7 +496,7 @@ void CJobManager::run()
         try
         {
             factory.setown(getWorkUnitFactory());
-            workunit.setown(factory->openWorkUnit(wuid, false));
+            workunit.setown(factory->openWorkUnit(wuid));
             if (!workunit) // check workunit is available and ready to run.
                 throw MakeStringException(0, "Could not locate workunit %s", wuid);
             if (workunit->getCodeVersion() == 0)