Bug 388770 - Provide a lazy adapting ChangeRecorder
Summary: Provide a lazy adapting ChangeRecorder
Status: NEW
Alias: None
Product: EMF
Classification: Modeling
Component: cdo.core (show other bugs)
Version: 4.13   Edit
Hardware: All All
: P3 enhancement with 1 vote (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-09-04 12:29 EDT by Anders Jönsson CLA
Modified: 2020-12-11 10:42 EST (History)
7 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Anders Jönsson CLA 2012-09-04 12:29:33 EDT
Provide a ChangeRecorder that can adapt itself lazily to CDO models with the goal to make the use of a CommandStack with undo/redo capability available to partly loaded CDO models.

---

A org.eclipse.emf.ecore.change.util.ChangeRecorder cannot be used together with partly loaded CDO models since the self adapting mechanism follows all references recursively until the whole containment graph has been loaded into memory.

CDO provides a CDOLazyContentAdapter that dynamically self-adapts to all objects that are loaded into memory by CDO. Referenced objects are loaded only when they are needed, hence the term "lazy"-loaded. For large CDO-models to take advantage of a CommandStack with undo/redo there has to be a ChangeRecorder that uses such a lazy adapting mechanism.

It would be favourable if the proposed "lazy" ChangeRecorder was compatible with the existing org.eclipse.emf.ecore.change.util.ChangeRecorder and so also with ChangeCommand. But ChangeCommand, ChangeRecorder and its adaption mechanism are currently "soldered" together in a way that makes reuse of the code in a CDO setting difficult.

Ideas:
- Make org.eclipse.emf.ecore.change.util.ChangeRecorder delegate the object adaption to a pluggable adapter (let it default to current behaviour). In this way a CDOLazyContentAdapter can be used when needed and all related EMF functionality can be reused by CDO-models.
- IF the org.eclipse.emf.common.notify.Adapter interface doesn't provide enough functionality for the ChangeRecorder, maybe a new interface with the functionality needed by a pluggable adapter can be introduced and then be implemented by CDOLazyContentAdapter.


There may be similarities with this bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=323792
Comment 1 Ed Merks CLA 2012-09-08 09:39:06 EDT
The only place in EMF core where ChangeRecorder is used is in ChangeCommand and that's not used anywhere else in EMF core.  I can't break the ChangeCommand API, so unless CDO extends ChangeRecorder, it can't reuse ChangeCommand.  CDO could certainly provide its own ChangeCommand that uses its own version of a change recorder, but then the problem just moves to downstream frameworks like EMF Transaction, and that code base is basically unsupported these days.

It's not clear that CDO can't just extend ChangeRecorder, perhaps specializing mostly the setTarget method to not aggressively adapt the whole containment tree. Until there is an answer to that questions, I'll assign this to CDO pending concrete suggestions for non-breaking changes I can make in EMF core to support greater flexibility.  If CDO can implement what it needs by extending ChangeRecorder, we could add some facility so that the following method in ChangeCommand can find an appropriate implementation, perhaps by looking for an adapter on the resource set...

  protected ChangeRecorder createChangeRecorder()
  {
    return new ChangeRecorder();
  }
Comment 2 Cristian CLA 2013-04-22 09:25:28 EDT
Based on the 2 previous comments, I come with the following idea:

a) Create a subclass of ChangeRecorder, let's say EContentAdapterDelegatingChangeRecorder.
b) This class overrides the original behavior that adds the adapter recursively on children. E.g. override .setTarget(), .addAdapter(), etc, in order to do nothing.
c) The new class would have an attribute of type EContentAdapter that is simply set on the root object when beginning recording. When EContentAdapter receives notifications (i.e. its notifyChanged() method), it would delegate to the changeRecorder.notifyChanged()
d) The above attribute could by a CDOLazyContentAdapter 

Does this proposition has any flaws? I would like to begin this kind of implementation, but I'm wondering if there are cases/scenarios that I'm missing.
Comment 3 Eike Stepper CLA 2013-04-22 13:46:13 EDT
I don't immediately see that something is missing and it seems cheap enough to try it.

Ed, do you have some hints for Cristian?

Anders, what about your implementation, do you still consider to attach it? And if it's "just" as a reference ;-)
Comment 4 Anders Jönsson CLA 2013-04-23 12:50:21 EDT
The subclassing of ChangeRecorder seems to be the right approach but I am not sure that it is as straight forward as proposed by Cristian (I may be wrong).
What you would want is a separation of the two concerns:
- Adding and removing the (ChangeRecorder) adapter
- The actual recording of changes

As it is these concerns don't seem to be separated at all (and probably for good reason). For example the targetObjects and originalTargetObject attributes in ChangeRecorder are accessed both in consolidateChanges() (which is change recording) and in setTarget() (which is adapting).

I haven't wrapped my head around all this but simply overriding setTarget() will hardly work.

Maybe there is a way to factor out the change recorder functionality from setTarget(). Then the ChangeRecorder subclass (i.e. the EContentAdapterDelegatingChangeRecorder from comment 2) would still need to *be* the adapter and intercept all the setTarget() etc calls in order to first(?) call the (delegate) EcontentAdapter and after(?) that the factored out change recorder functionality.

Also, there is a bug in CDOLazyContentAdapter that needs fixing:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=405483

///Anders
Comment 5 Eike Stepper CLA 2013-05-20 07:04:21 EDT
Anders, what about your implementation, do you still consider to attach it? And if it's "just" as a reference ;-)
Comment 6 Anders Jönsson CLA 2013-05-20 08:33:21 EDT
My "implementation" has so many problems, partly caused by a desire to make it work without changes to the EMF code and to work around bugs (like 323792). It doesn't subclass ChangeRecorder, instead it subclasses CDOLazyContentAdapter and delegates to ChangeRecorder. And so it is not compatible with... anything. Sure I can attach it, but, besides being really hard to follow, it just wouldn't be a step in the right direction.

On the other hand, I have decided to try and contribute something more like what is discussed in this bug, i.e. subclassing ChangeRecorder and delegating to an Adapter.
Comment 7 Eike Stepper CLA 2013-06-27 04:09:07 EDT
Moving all outstanding enhancements to 4.3
Comment 8 Eike Stepper CLA 2014-08-19 09:28:45 EDT
Moving all open enhancement requests to 4.4
Comment 9 Eike Stepper CLA 2014-08-19 09:37:49 EDT
Moving all open enhancement requests to 4.4
Comment 10 Esteban DUGUEPEROUX CLA 2015-04-02 11:48:42 EDT
By default ChangeRecorder & its descendant TransactionChangeRecorder are lazy according to EMF API, i.e. using EObject.eIsProxy() and InternalEList.basicIterator(). Then if we had EMF proxy support in CDO, we would have a lazy ChangeRecorder for free. See Bug 392720
Comment 11 Eike Stepper CLA 2015-07-14 02:15:33 EDT
Moving all open bugzillas to 4.5.
Comment 12 Eike Stepper CLA 2016-07-31 00:58:38 EDT
Moving all unaddressed bugzillas to 4.6.
Comment 13 Eike Stepper CLA 2017-12-28 01:21:10 EST
Moving all open bugs to 4.7
Comment 14 Eike Stepper CLA 2019-11-08 02:16:03 EST
Moving all unresolved issues to version 4.8-
Comment 15 Eike Stepper CLA 2019-12-13 12:43:16 EST
Moving all unresolved issues to version 4.9
Comment 16 Eike Stepper CLA 2020-12-11 10:42:10 EST
Moving to 4.13.