Community
Participate
Working Groups
A common pattern used in the GMF runtime and in clients of the GMF runtime is the creation of an AbstractTransactionalCommand (extends AbstractEMFOperation) that implements #doExecuteWithResult(IProgressMonitor, IAdaptable) (called from #doExecute(IProgressMonitor, IAdaptable)) with logic like this: protected CommandResult doExecuteWithResult( IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException { // The delegate command might be obtained from and EditPart, // or some other service. Obtaining the correct command requires // knowledge of the system at the time this command is executed, // not at the time of its creation. AbstractEMFoperation delegateCommand = getMyDelegateCommand(); if (delegateCommand != null && delegateCommand.canExecute()) { IStatus status = delegateCommand.execute(progressMonitor, info); return new CommandResult(status); } return CommandResult.newErrorCommandResult("Delegate not executable"); } One problem with this pattern is that there is no way for the delegateCommand to reuse the currently active write transaction. #isReuseParentTransaction() will always return false, and there is no way for the client to change its value. The creation of unnecessary transactions can have a negative impact on performance (see bug 141051). Please consider the addition of API to allow clients to reuse the active write transaction in this scenario.
Created attachment 111080 [details] JUnit to demonstrate the desired behaviour.
Also, please consider including API with which the client can indicate that that the delegateCommand wants to use the same transaction options as the currently active transaction. I know it is possible to obtain the options from the active transaction through the editing domain (InternalTransactionalEditingDomain.getActiveTransaction().getOptions()), but it would be much more convenient if this could be built into the new API.
(In reply to comment #2) > Also, please consider including API with which the client can indicate that > that the delegateCommand wants to use the same transaction options as the > currently active transaction. I don't follow. Why would a client of a command know anything about the options required by a delegate? Presumably clients don't even know about the existence of the delegate (which is encapsulated). Otherwise, they would just set the delegate's options. Note, also, that if the delegate doesn't specify any options, then when it is executed, its would only inherit the options from the active transaction, anyway, so not creating a new transaction in that case would be fine. I think that simply not specifying options on the delegate should suffice, but as I said, I don't think I understand tho problem. BTW, the Priority filed is not a user field; Severity is. The committer team uses the priority in planning the schedule.
(In reply to comment #3) >I don't follow. Why would a client of a command know anything about the >options required by a delegate? Presumably clients don't even know about the By client, I meant the command itself that is executing the delegate directly. Sorry if that wasn't clear. I want to be sure that I can use the active transaction in this scenario. In other words, that I can make this check in #execute(IProgressMonitor, IAdaptable) be false when #isReuseParentTransaction() is true: if (!isReuseParentTransaction() || optionsDiffer(options)) { However, I find that the options always differ even when the delegateCommand hasn't explicitly specified any options of it's own. For example, by the time this #optionsDiffer is invoked, my delegateCommand (which was instantiated without explicit options) passes options of {block_cd_prop=true, _owning_operation=Deferred Layout()} into #optionsDiffer, but the active transaction options are {block_cd_prop=true, validate_edit=org.eclipse.gmf.runtime.emf.core.GMFEditingDomainFactory$2@16e016e, _owning_operation=Deferred Layout()} When you say: > Note, also, that if the delegate doesn't specify > any options, then when it is executed, its would only inherit the options > from the active transaction, anyway are there any exceptions to this rule?
(In reply to comment #4) Thanks, that is now well understood. > When you say: > > Note, also, that if the delegate doesn't specify > > any options, then when it is executed, its would only inherit the options > > from the active transaction, anyway > > are there any exceptions to this rule? There may be. That will depend on the transaction implementation. We will probably need to add API into the transactions to allow the framework to query inheritability of options and other relevant properties.
(In reply to comment #5) > > probably need to add API into the transactions to allow the framework to query > inheritability of options and other relevant properties. This is to be addressed by bug 245446, so this bug will cover the original problem of execution of non-nested commands in ad hoc fashion.
Thanks for the JUnit test! Fix committed to HEAD. Basically, the existing API that was package-private is made public.
Restore original target after milestones were deranged.