Daisy-chaining deliver participant foiled by auto-complete
So I have a phase 2 deliver participant whose intent is to capture a workspace-to-stream deliver event and automatically deliver those same changesets to one or more other streams.
This works fine if the changeset was in Complete state when the user did the initial deliver. If it isn't, I get one of two different errors if I attempt to further deliver on to the secondary stream via my code. RTC is of course auto-completing the changesets somewhere along the way with its own advisor/participant code, but I can't figure out how to access the completed state of the changesets.
If I have my code deliver the changesets from the workspace, I get this:
The operation cannot be run because the repository contains a newer version of the item it tried to modify.
If I have my code deliver from the stream that the user delivered to, I get this:
Cannot close change set that is not active in workspace or in suspended list.
Both of these tactics work fine as long as the changesets are in Complete state before the user delivers.
This is how I'm getting the changesets and delivering them:
IScmDeltaSource sourceData = (IScmDeltaSource)(operation.getOperationData()); Iterable<IChangeHistoryAddOperandDelta> deltas = sourceData.getDeltas( IChangeHistoryAddOperandDelta.class );Is there any way to do this without the user having to manually complete changesets before delivering?
for (IChangeHistoryAddOperandDelta delta : deltas)
{
ArrayList<IChangeSetHandle> allChanges = new ArrayList<IChangeSetHandle>();
Iterable<IChangeSetHandle> changeSetHandles1 = delta.getAdditionalChangeSets( component );
Iterable<IChangeSetHandle> changeSetHandles2 = delta.getAdditionalBaselineChangeSets( component );
for (IChangeSetHandle changeSetHandle : changeSetHandles1)
allChanges.add( changeSetHandle );
for (IChangeSetHandle changeSetHandle : changeSetHandles2)
allChanges.add( changeSetHandle );
scmService.deliverCombined( srcWorkspaceOrStream, null,
tgtWorkspaceOrStream, new IBaselineHandle[] {},
allChanges.toArray( new IChangeSetHandle[] {} ), null, null, null, null );
}
One answer
Long story short is that you will not be able to do this from within the 'process advisor' code. You cannot perform 'write' operations like this during an advisor because the advisor itself will not complete it's 'write' operations until the end of it's operation/transaction. For example, a delivery of open change sets may have occurred, at which point advisors are run to 'check' (read) various states to determine if everything is "acceptable" to continue. Once all the advisor checks 'pass', then the deliver operation/transaction completes, which would 'write' to the database the new states of the change sets (which will be closed on delivery) and it would also record the actual delivery in the target stream, etc.. Given all this, it makes sense that a StaleDataExceptions or similar issues would happen if you tried various 'write' operations from within the running advisor.