Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HPCC-31143 Extend ICodeContext with getWorkflowId #18232

Merged
merged 1 commit into from
Feb 6, 2024

Conversation

shamser
Copy link
Contributor

@shamser shamser commented Jan 17, 2024

Extend ICodeContext with a new method called getWorkflowId. Implement wrapper for IEclProcess so that when IEclProcess::perform is called, 1) the ::perform passes the call through to the original IEclProcess perform but with a new IGlobaCodeContext. All other methods are passed through to the original IEclProcess.
2) this new IGlobalCodeContext wraps the orignal IGlobalCodeContext to call the original IGlobalCodeContext method but with a new queryCodeContext method implmentnation. The new queryCodeContext returns a new ICodeContext.
3) This new ICodeContext is the original ICodeContext wrapped with a class that overrides the getWorkflowId to return the workflow id.

Type of change:

  • This change is a bug fix (non-breaking change which fixes an issue).
  • This change is a new feature (non-breaking change which adds functionality).
  • This change improves the code (refactor or other change that does not change the functionality)
  • This change fixes warnings (the fix does not alter the functionality or the generated code)
  • This change is a breaking change (fix or feature that will cause existing behavior to change).
  • This change alters the query API (existing queries will have to be recompiled)

Checklist:

  • My code follows the code style of this project.
    • My code does not create any new warnings from compiler, build system, or lint.
  • The commit message is properly formatted and free of typos.
    • The commit message title makes sense in a changelog, by itself.
    • The commit is signed.
  • My change requires a change to the documentation.
    • I have updated the documentation accordingly, or...
    • I have created a JIRA ticket to update the documentation.
    • Any new interfaces or exported functions are appropriately commented.
  • I have read the CONTRIBUTORS document.
  • The change has been fully tested:
    • I have added tests to cover my changes.
    • All new and existing tests passed.
    • I have checked that this change does not introduce memory leaks.
    • I have used Valgrind or similar tools to check for potential issues.
  • I have given due consideration to all of the following potential concerns:
    • Scalability
    • Performance
    • Security
    • Thread-safety
    • Cloud-compatibility
    • Premature optimization
    • Existing deployed queries will not be broken
    • This change fixes the problem, not just the symptom
    • The target branch of this pull request is appropriate for such a change.
  • There are no similar instances of the same problem that should be addressed
    • I have addressed them here
    • I have raised JIRA issues to address them separately
  • This is a user interface / front-end modification
    • I have tested my changes in multiple modern browsers
    • The component(s) render as expected

Smoketest:

  • Send notifications about my Pull Request position in Smoketest queue.
  • Test my draft Pull Request.

Testing:

Copy link

Copy link
Member

@jakesmith jakesmith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shamser - please see comments.

@ghalliday - a couple of questions for you also.

// can construct an ICodeContext that returns the workflow id.
// (It cannot be done by wrapping IGlobalCodeContext because workflow id is known only when
// IEclProcess::perform is called. Workflow id isn't known before that.)
struct THORHELPER_API EclProcessEx : implements IEclProcess, public CInterface
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trivial: CInterfaceOf is preferable - avoids a VMT.

struct THORHELPER_API EclProcessEx : implements IEclProcess, public CInterface
{
// Wraps ICodeContext and overrides getWorkflowId() method
class CodeContextEx : extends IndirectCodeContext
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: better to be 'public' here. There may be exceptions, I think 'extends' should only be used when defining a new interface that's an extension of another, not when deriving a concrete class and/or defining a new concrete class.

virtual void fail(int, const char *) { gctx->fail(0, NULL); }

virtual bool isResult(const char * name, unsigned sequence) { return gctx->isResult(name, sequence); }
virtual unsigned getWorkflowId() const override { return gctx->getWorkflowId(); }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: the rest of the methods in GlobalCodeContextExtra would also benefit from 'override's.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think IGlobalCodeContext::getWorkflowId() is or will be actually used anywhere?

ICodeContext::getWorkflowId() will be, but I don't see anywhere that can call IGlobalCodeContext::getWorkflowId() directly, or via generated code ?

I think it must remain untouched though (not removed), because it will break pre-existing queries if it is removed (if the VMT changes).

@ghalliday - if it is never used (I removed it and definitions as a test and can't see anywhere that generates it), and it's never needed. If we can't remove it (to avoid breaking queries), can we rename it as ```
virtual unsigned deprecatedGetWorkUnitId() // no longer used, but keeping to preserve VMT integrity


?

private:
Owned<IEclProcess> eclProcess;
public:
IMPLEMENT_IINTERFACE;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

won't be needed with change to CInterfaceOf

@@ -1925,7 +1925,7 @@ void EclAgent::doProcess()
}
{
MTIME_SECTION(queryActiveTimer(), "Process");
Owned<IEclProcess> process = loadProcess();
Owned<IEclProcess> process = new EclProcessEx(loadProcess());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

related to our previous offline discussion, I'm still not sure why IEclProcess needs to be wrapped...

where workflow is needed, eclagent calls:
EclAgent::runProcess-> WorkflowMachine::perform, which ultimately calls IEclProcess->perform in a couple of places (WorkflowMachine::performItem and WorkflowMachine::performItemParallel)

Is there any reason why they can't use a GlobalCodeContextExtra wrapper at that point, avoiding the need to wrap IEclProcess as well e.g.:

void WorkflowMachine::performItem(unsigned wfid, unsigned scheduledWfid)
{
#ifdef TRACE_WORKFLOW
    if(currentWfid)
        LOG(MCworkflow, "Branching from workflow item %u", currentWfid);
    LOG(MCworkflow, "Performing workflow item %u", wfid);
#endif
    wfidStack.append(currentWfid);
    wfidStack.append(scheduledWfid);
    currentWfid = wfid;
    currentScheduledWfid = scheduledWfid;
    timestamp_type startTime = getTimeStampNowValue();

    **GlobalCodeContextExtra gctx(ctx, wfid);**
    CCycleTimer timer;
    **process->perform(&gctx, wfid);**
    noteTiming(wfid, startTime, timer.elapsedNs());
    scheduledWfid = wfidStack.popGet();
    currentWfid = wfidStack.popGet();
    if(currentWfid)
    {
#ifdef TRACE_WORKFLOW
        LOG(MCworkflow, "Returning to workflow item %u", currentWfid);
#endif
    }
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that would work equally well, and probably simpler.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a potential danger if any function does not use this context that the calling code will not get the workflow id. E.g. The IcodeContext used within a graph.

Combined with your other comment about IGlobalCodeContext::getWorkflowId(), I wonder whether it should only appear in the IGlobalCodeContext. That would still be accessible from the dfu functions if they indicated they required it.

@@ -2876,7 +2876,7 @@ class CRoxieServerContext : public CRoxieContextBase, implements IRoxieServerCon
MTIME_SECTION(myTimer, "Process");
QueryTerminationCleanup threadCleanup(true);
EclProcessFactory pf = (EclProcessFactory) factory->queryDll()->getEntry("createProcess");
Owned<IEclProcess> p = pf();
Owned<IEclProcess> p = new EclProcessEx(pf());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comment/question in eclagent.cpp re. whether IEclProcess wrapper needed

@@ -4029,7 +4032,7 @@ class CSoapRoxieServerContext : public CRoxieServerContext
virtual void process()
{
EclProcessFactory pf = (EclProcessFactory) factory->queryDll()->getEntry("createProcess");
Owned<IEclProcess> p = pf();
Owned<IEclProcess> p = new EclProcessEx(pf());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see comment/question in eclagent.cpp re. whether IEclProcess wrapper needed

@@ -727,6 +727,7 @@ interface ICodeContext : public IResourceContext
virtual char *getPlatform() = 0; // caller frees return string.
virtual unsigned getPriority() const = 0;
virtual char *getWuid() = 0; // caller frees return string.
virtual unsigned getWorkflowId() const = 0; // Note: don't use yet as it has not been fully implemented in all derived classes
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need to place any new virtuals at end of interface.
This will allow existing queries compiled with previous version to continue to work without recompilation, if methods are placed in the middle, the VMT offsets of methods past it will change and cause problems.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it needs to be at the end of the interface, and it cannot match the name of an existing virtual either.

@@ -2954,7 +2955,7 @@ struct IGlobalCodeContext
virtual void fail(int, const char *) = 0;

virtual bool isResult(const char * name, unsigned sequence) = 0;
virtual unsigned getWorkflowId() = 0;
virtual unsigned getWorkflowId() const = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

related to comment in thorcommon.hpp.
Can we rename it to avoid confusion? If not, is changing it's prototype from non-const to const problematic (does it affect VMT alignment of other members. I don't think so, but would like @ghalliday to comment on this and previous comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IGlobalCodeContext had getWorkflowId() defined before this PR. I added getWorkflowId() to ICodeContext in this PR. Some classes such as EclAgent derive from both IGlobalCodeContext and ICodeContext. Would it make sense to have both const and non-const defined in the classes such as EclAgent?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I realize it was already there, but now with a new method in ICodeContext, the pre-existing IGlobalCodeContext version (especially if never used) adds to the confusion.

Would it make sense to have both const and non-const defined in the classes such as EclAgent?

I don't think it would be a good idea to have a const and non-const version, that would be more confusing.

I think IGlobalCodeContext ::getWorkflowid() could be deprecated.
[ see other comment : https://github.com//pull/18232#discussion_r1457347909 ]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think changing from const to non const will cause any problems. The danger is with failing to load workunit dlls that have references to old base definitions, but that should not happen with anything within IGlobalCodeContext.

IGlobalCodeContext ::getWorkflowid() was deprecated because it was incompatible with the parallel workflow execution. This PR would have probably been a better way to get around that problem...

@@ -77,6 +77,7 @@ if(NOT PLUGIN)
nbcd
eclrtl
deftype
thorhelper
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be avoided, better not to propagate the engine library thorhelper into workunit if it can be avoided.

This is being included because of IndirectCodeContext ?
Apart from 2 virtuals it actually implements differently, a vanilla IndirectCodeContext could be moved out of thorhelper.
And the version that is needed by the engines (by thorcommon) could derive from the generic IndirectCodeContext and overload the 2 methods.

@shamser shamser force-pushed the issue31143 branch 2 times, most recently from d9f4dff to 3226e7c Compare January 19, 2024 14:51
@shamser shamser requested a review from jakesmith January 19, 2024 14:53
Copy link
Member

@ghalliday ghalliday left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shamser one main comment about the location of the class implementations - conclusion to move them to another file built in the same dll, and a couple of other observations.
Looks close to being ready to merge.

};

class IndirectCodeContext : implements ICodeContext
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These classes need to be in a different file - this is used from generated code, and should contain the minimum possible - especially no implementations.

There is also a second danger of including class implementations in a header. If a compiler only sees one concrete implementation of a class it will add code to de-virtualise the function calls (possibly only if it has an inline function definition, I have forgotten!). That does not work well if the implementation is in a different dll, and also is counter-productive if it is not the most common implementation.

Having said that it isn't clear where this class should go if it is being called from the workflow. I think the correct answer may be that the code in workflow.cpp needs to split in two, the workflowMachine should be moved to throhelper, and this should live in thorhelper as it did originally.

A less painful solution would be to add a new header/c++ file to eclrtl, but move it out of this file.

};

class IndirectCodeContext : implements ICodeContext
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a export qualifier otherwise you may get link problem in windows, or with release versions.

class ECLRTL_API IndirectCodeContext : implements ICodeContext

virtual unsigned getWorkflowId() const override { return wfid; }
};
IGlobalCodeContext * gctx;
CodeContextEx * codeContextEx;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor. This could be a member object rather than a pointer, avoiding the need for the new/delete.

unsigned wfid;
public:
CodeContextEx(ICodeContext * _ctx, unsigned _wfid) : IndirectCodeContext(_ctx), wfid(_wfid) {}
virtual ~CodeContextEx() {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not needed?

@jakesmith
Copy link
Member

@shamser The windows-2022 build is failing:

     Creating library D:/a/HPCC-Platform/HPCC-Platform/build/bin/RelWithDebInfo/workunit.lib and object D:/a/HPCC-Platform/HPCC-Platform/build/bin/RelWithDebInfo/workunit.exp
workflow.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl GlobalCodeContextExtra::GlobalCodeContextExtra(struct IGlobalCodeContext *,unsigned int)" (__imp_??0GlobalCodeContextExtra@@QEAA@PEAUIGlobalCodeContext@@I@Z) referenced in function "protected: void __cdecl WorkflowMachine::performItem(unsigned int,unsigned int)" (?performItem@WorkflowMachine@@IEAAXII@Z) [D:\a\HPCC-Platform\HPCC-Platform\build\common\workunit\workunit.vcxproj]

I am not sure why exactly. From the errors, it would appear that the symbols are not being exported from the eclrtl lib, but the DECL spec looks correct afaics.

@ghalliday - may have some insight.

Copy link
Member

@jakesmith jakesmith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shamser - looks good, some v. minor issues, and need to workout why it's failing to compile in windows-2022

roxie/ccd/ccdcontext.cpp Outdated Show resolved Hide resolved
unsigned wfid;
public:
CodeContextEx(ICodeContext * _ctx, unsigned _wfid) : IndirectCodeContext(_ctx), wfid(_wfid) {}
virtual ~CodeContextEx() {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#18232 (comment)

Still not needed afaics.

protected:
ICodeContext * ctx;
};
class ECLRTL_API GlobalCodeContextExtra : implements IGlobalCodeContext
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trivial/formatting: normally we have a newline between class declarations.

virtual unsigned getWorkflowId() const override { return wfid; }
};
IGlobalCodeContext * gctx;
CodeContextEx codeContextEx;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

personal: could have named instance at end of class definition, i.e.:

        virtual unsigned getWorkflowId() const override { return wfid; }
    } codeContextEx;

rtl/eclrtl/wfcontext.hpp Outdated Show resolved Hide resolved
virtual void setResultDataset(const char * name, unsigned sequence, size32_t len, const void *val, unsigned numRows, bool extend) override { gctx->setResultDataset(name, sequence, len, val, numRows, extend); }
virtual void getEventName(size32_t & outLen, char * & outStr) override { gctx->getEventName(outLen, outStr); }
virtual void getEventExtra(size32_t & outLen, char * & outStr, const char * tag) override { gctx->getEventExtra(outLen, outStr, tag); }
virtual void doNotify(char const * name, char const * text, const char * target) override{ gctx->doNotify(name, text, target); }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trivial/formatting: missing space after override

@shamser
Copy link
Contributor Author

shamser commented Jan 25, 2024

@shamser The windows-2022 build is failing:

     Creating library D:/a/HPCC-Platform/HPCC-Platform/build/bin/RelWithDebInfo/workunit.lib and object D:/a/HPCC-Platform/HPCC-Platform/build/bin/RelWithDebInfo/workunit.exp
workflow.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl GlobalCodeContextExtra::GlobalCodeContextExtra(struct IGlobalCodeContext *,unsigned int)" (__imp_??0GlobalCodeContextExtra@@QEAA@PEAUIGlobalCodeContext@@I@Z) referenced in function "protected: void __cdecl WorkflowMachine::performItem(unsigned int,unsigned int)" (?performItem@WorkflowMachine@@IEAAXII@Z) [D:\a\HPCC-Platform\HPCC-Platform\build\common\workunit\workunit.vcxproj]

I am not sure why exactly. From the errors, it would appear that the symbols are not being exported from the eclrtl lib, but the DECL spec looks correct afaics.

@ghalliday - may have some insight.

I'm not convinced that GlobalCodeContextExtra and IndirectCodeContext is in the right place. sourcedoc.xml in eclrtl states:
Eclrtl should only contain code that is needed by the code generator - **it is not a library for sharing code between the engines**. In particular it should not have any activity related code (that should go in thorhelper)
It seems to me that common/thorhelper would be a more suitable directory. It contains various helpers for both roxie and thor. What do you think?

@shamser shamser marked this pull request as draft January 26, 2024 10:31
@shamser shamser force-pushed the issue31143 branch 3 times, most recently from 66b58a6 to de52c75 Compare January 26, 2024 11:54
@ghalliday
Copy link
Member

@shamser @jakesmith
Another way of dealing with the dependency problem is to not have the globalcontext mapping in workflow engine, but have it in the engine (using the original idea of a IProcess that reimplements the interface). I suspect it is better to keep it as it is though - the problem is really that the workflow processing code is in the wrong place.

@shamser shamser marked this pull request as ready for review January 26, 2024 13:39
@shamser shamser requested a review from jakesmith January 26, 2024 13:39
Copy link
Member

@ghalliday ghalliday left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As for the link problem, I have a personal dislike of classes with lots of inline functions, especially in headers. In this case the functions would be duplicated into every dll that uses them.

Having said that I'm not 100% sure why you are getting the link error. A fix would be to
i) define a cpp file within eclrtl that includes that header
ii) add ECLRTL_API to the class definitions in the header.
iii) imho also move the implementation of those virtuals into the c++ file. Although just doing the first 2 steps may fix it.

public:
GlobalCodeContextExtra(IGlobalCodeContext * _gctx, unsigned _wfid) : codeContextEx(_gctx->queryCodeContext(), _wfid), gctx(_gctx) {}
virtual ICodeContext * queryCodeContext() override { return &codeContextEx; }
virtual void fail(int, const char *) override { gctx->fail(0, NULL); }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not passing the parameters through correctly.

@jakesmith
Copy link
Member

As for the link problem, I have a personal dislike of classes with lots of inline functions, especially in headers. In this case the functions would be duplicated into every dll that uses them.

Having said that I'm not 100% sure why you are getting the link error. A fix would be to i) define a cpp file within eclrtl that includes that header ii) add ECLRTL_API to the class definitions in the header. iii) imho also move the implementation of those virtuals into the c++ file. Although just doing the first 2 steps may fix it.

Looks like wfcontext.cpp is currently missing from the branch.
And re. Gavin's comments above, IndirectCodeContext currently does not have ECLRTL_API, and as far as I can see will also need same treatment as GlobalCodeContextExtra.

Copy link
Member

@jakesmith jakesmith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shamser - commenting mostly, because I think you're still refactoring, but I'm tagged for review.

@shamser shamser force-pushed the issue31143 branch 2 times, most recently from 69482df to bfcc162 Compare January 29, 2024 13:34
@shamser shamser requested a review from jakesmith January 29, 2024 14:06
Copy link
Member

@jakesmith jakesmith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shamser - a few minor comments

process->perform(this, 0);
{
GlobalCodeContextExtra gctx(this, 0);
process->perform(&gctx, 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder whether if would be better to pass 'this' (as before), and have the EclAgent::getWorkflowId() method return 0;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would improve the code at best minimally. I'd prefer to leave as is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am not concerned it is inefficient or problematic as it stands.
It is more a question of under what circumstances can this branch be used, and when it is, does it make sense for ICodeContext::getWorkflowId() to return 0 (and what does that mean?), or should it never be called in which case the EclAgent::getWorkflowId() version that returns throwUnexpected() is more correct.

I am not sure how or when workflow does not exist, so the point is probably moot anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect this could be changed so that it throws an error if it does not have workflow. I think it has always been present for the past 15+ years.

@@ -567,6 +567,7 @@ class CRoxieAgentActivity : implements CInterfaceOf<IRoxieAgentActivity>, implem
// Not yet thought about these....

virtual char *getWuid() { throwUnexpected(); } // caller frees return string.
virtual unsigned getWorkflowId() const override { throwUnexpected(); }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trivial: in fact expected, but unimplemented at the moment? (maybe change to UNIMPLEMENTED_X("getWorkflowId"); )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't missing functionality. This getWorkflowId shouldn't be called. I think it should remain as throwUnexpected.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it's not used anyway yet, it doesn't matter anyway,
but do still wonder if could be via CRoxieAgentActivity::onCreate()

        basehelper->onCreate(this, NULL, &serializedCreate);

where this is the ICodeContext of CRoxieAgentActivity, where this is the implemented member.

Anyway, if it is an issue it can be revisited in https://track.hpccsystems.com/browse/HPCC-31154.

roxie/ccd/ccdcontext.cpp Outdated Show resolved Hide resolved
Extend  ICodeContext with a new method called getWorkflowId.
Implement wrapper for IEclProcess so that when IEclProcess::perform is called,
1) the ::perform passes the call through to the original IEclProcess perform but with a new IGlobaCodeContext.  All other methods are passed through to the original IEclProcess.
2) this new IGlobalCodeContext wraps the orignal IGlobalCodeContext to call the original IGlobalCodeContext method but with a new queryCodeContext method implmentnation.   The new queryCodeContext returns a new ICodeContext.
3) This new ICodeContext is the original ICodeContext wrapped with a class that overrides the getWorkflowId to return the workflow id.

Signed-off-by: Shamser Ahmed <[email protected]>
Copy link
Member

@jakesmith jakesmith left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to merge to me.

@ghalliday ghalliday merged commit 5f9b805 into hpcc-systems:master Feb 6, 2024
49 of 50 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants