Bug 245393 - Allow transaction reuse in direct command execution
Summary: Allow transaction reuse in direct command execution
Status: RESOLVED FIXED
Alias: None
Product: EMF Services
Classification: Modeling
Component: Transaction (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P2 enhancement
Target Milestone: ---   Edit
Assignee: Christian Damus CLA
QA Contact:
URL:
Whiteboard: Client Control
Keywords: contributed, plan
Depends on:
Blocks:
 
Reported: 2008-08-27 11:03 EDT by Linda Damus CLA
Modified: 2017-02-24 15:11 EST (History)
1 user (show)

See Also:


Attachments
JUnit to demonstrate the desired behaviour. (2.66 KB, patch)
2008-08-27 11:06 EDT, Linda Damus CLA
give.a.damus: iplog+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Linda Damus CLA 2008-08-27 11:03:10 EDT
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.
Comment 1 Linda Damus CLA 2008-08-27 11:06:55 EDT
Created attachment 111080 [details]
JUnit to demonstrate the desired behaviour.
Comment 2 Linda Damus CLA 2008-08-27 12:08:44 EDT
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.
Comment 3 Christian Damus CLA 2008-08-27 14:00:43 EDT
(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.
Comment 4 Linda Damus CLA 2008-08-27 14:58:01 EDT
(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?
Comment 5 Christian Damus CLA 2008-08-27 15:46:19 EDT
(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.
Comment 6 Christian Damus CLA 2008-09-13 17:05:02 EDT
(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.
Comment 7 Christian Damus CLA 2008-09-21 17:21:08 EDT
Thanks for the JUnit test!  Fix committed to HEAD.  Basically, the existing API that was package-private is made public.
Comment 8 Christian Damus CLA 2008-11-24 13:10:30 EST
Restore original target after milestones were deranged.