Bug 350120 - Transition TRANSIENT with Event INVALIDATE/DETACH_REMOTE doesn't become CONFLICT state
Summary: Transition TRANSIENT with Event INVALIDATE/DETACH_REMOTE doesn't become CONFL...
Status: ASSIGNED
Alias: None
Product: EMF
Classification: Modeling
Component: cdo.core (show other bugs)
Version: 4.13   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Egidijus Vaisnora CLA
QA Contact: Eike Stepper CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-06-23 04:19 EDT by Egidijus Vaisnora CLA
Modified: 2020-12-11 10:41 EST (History)
1 user (show)

See Also:
vaisegid: review? (stepper)


Attachments
Test case v1 (3.14 KB, patch)
2011-06-23 04:22 EDT, Egidijus Vaisnora CLA
no flags Details | Diff
TestCase&patch v2 (14.33 KB, patch)
2011-06-28 03:34 EDT, Egidijus Vaisnora CLA
no flags Details | Diff
Demo of the problem with this approach (17.09 KB, patch)
2011-07-03 07:25 EDT, Eike Stepper CLA
no flags Details | Diff
patch v3 (21.88 KB, patch)
2011-07-11 10:59 EDT, Egidijus Vaisnora CLA
no flags Details | Diff
Patch v3 (23.36 KB, patch)
2011-07-16 06:06 EDT, Egidijus Vaisnora CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Egidijus Vaisnora CLA 2011-06-23 04:19:35 EDT
Related to bug
https://bugs.eclipse.org/bugs/show_bug.cgi?id=309305

I got to this problem too. However solution, provided in this issue leads to
model inconsistency. Suppose we have users user1 and user2. Both are working on
container A.

user2 detaches A
user1 creates child B in container A
user1 commit
user2 refresh session
user2 commits

User2 transaction is committed. Object A is TRANSIENT for user2, but for user1
become INVALID. User1 has element B in CLEAN state, while it's parent is
already removed from store. Thus we have garbage in the store. Worst thing that
we got to this state silently.
IMO expected behavior is to bring A to CONFLICT state and prevent user2 from
corrupting model silently. Pascal proposed conflict like solution from the
beginning. Why we couldn't go this direction?
Comment 1 Egidijus Vaisnora CLA 2011-06-23 04:22:59 EDT
Created attachment 198454 [details]
Test case v1
Comment 2 Eike Stepper CLA 2011-06-23 06:27:58 EDT
When user2 detaches A then this object becomes TRANSIENT and is no longer under the control of the transaction (with the exception that it would be recognized in case of reattachment). The object could even have been attached to a different transaction in the meantime. why should it have any other state than transient?
Comment 3 Egidijus Vaisnora CLA 2011-06-23 07:20:57 EDT
(In reply to comment #2)

Transaction can commit object as detached or it can restore it back to previous state. I would call this control over "server" object, more precisely, control over object removal. I am not certain what will happen, if you move object to different transaction, but I suppose, previous transaction will take care to remove server object by it's CDOID. New transaction, even if it holds reference to the same local object, will introduce new server object with a new CDOID.
Comment 4 Eike Stepper CLA 2011-06-23 08:00:00 EDT
(In reply to comment #3)
> Transaction can commit object as detached 

Not exactly. It would commit the parent object which is DIRTY at that time.

> or it can restore it back to previous
> state. I would call this control over "server" object, more precisely, control
> over object removal. 

I'm not sure what you mean by this.

> I am not certain what will happen, if you move object to
> different transaction, but I suppose, previous transaction will take care to
> remove server object by it's CDOID. 

It does not matter so much what happens to the object after detachment. Conceptually it seems odd that the object state is stored *within* the objects, while it only has a meaning in the context of a CDOView. But that's probably a different discussion.

> New transaction, even if it holds reference
> to the same local object, will introduce new server object with a new CDOID.

Yes.

So, why should an object that has been detached have a CONFLICT?
Comment 5 Egidijus Vaisnora CLA 2011-06-23 08:51:19 EDT
> So, why should an object that has been detached have a CONFLICT?

Because it is a conflict. Attached test case, illustrate typical svn like tree conflict. User2 and User1 made changes to the same object at the same time. While user2 removes object, it must take into account user1 changes, made before last update.

Additionally, if you change "expected" value to "false" in the test, you will enable current behavior, where you can see, how user2 successfully commits his changes and leaves orphan "child" in remote repository. User2 was making changes to remote object, not having the whole model locally and worst, it was made silently. How could user2 detect conflict in this case by having current CDO implementation?
Comment 6 Eike Stepper CLA 2011-06-23 09:01:15 EDT
(In reply to comment #5)
> > So, why should an object that has been detached have a CONFLICT?
> 
> Because it is a conflict. 

I don't see that. That object will not even be committed anymore.

> Attached test case, illustrate typical svn like tree
> conflict. 

CDO does not claim to behave like SVN.

> User2 and User1 made changes to the same object at the same time.
> While user2 removes object, it must take into account user1 changes, made
> before last update.

I don't see that. It must take into account changes that others have applied to the parent object. And it does.

> Additionally, if you change "expected" value to "false" in the test, you will
> enable current behavior, where you can see, how user2 successfully commits his
> changes and leaves orphan "child" in remote repository. User2 was making
> changes to remote object, not having the whole model locally and worst, it was
> made silently. How could user2 detect conflict in this case by having current
> CDO implementation?

I'll test all this later. Today (day 1 after the release) my workspaces are not very usable, yet.
Comment 7 Egidijus Vaisnora CLA 2011-06-24 06:48:28 EDT
(In reply to comment #6)
> I don't see that. That object will not even be committed anymore.

Maybe, I do not understand your position, but it looks like you are claiming that there are no conflict as was no object editing. You don't need to commit object in order to remove. It is enough to send CDOID of removed object. But, regardless how you inform server side about object removal, it is object modification.
 
> CDO does not claim to behave like SVN.

Yes, but SVN, like other version control system, deals with concurrent modification and conflict solving. Tree conflict is one of such conflict types and it has nothing to do with SVN as a tool. It is rather common concurrent modification issue. CDO is also solving concurrent modification problems and finds conflicts. Thus tree conflict shouldn't be exclusion and CDO must provide way or strategy how to solve it. However current provided strategy (ignoring) is straight way to model corruption, which IMO should not be acceptable. 

> I don't see that. It must take into account changes that others have applied to
> the parent object. And it does.

Perhaps we are not talking about the same situation, but problem is, that object detaching doesn't take into account about newer version on the server. Parent object is handled correctly and it cannot protect concurrent changes made in children level. I think, in the test case this situation is obvious.
Comment 8 Egidijus Vaisnora CLA 2011-06-28 03:34:44 EDT
Created attachment 198708 [details]
TestCase&patch v2

I let my self to develop premature patch. Covers conflict creation on invalidation, when client has TRANSIENT, while from server comes newer version. 
If we moving to conflict solving based direction, then second part of the patch must be developed. It shuold cover situatuation, when user will attempt to commit TRANSIENT, while on server is newer version. Server must throw exception about newer version.
Comment 9 Eike Stepper CLA 2011-07-03 07:25:40 EDT
Created attachment 199008 [details]
Demo of the problem with this approach

Please look at the second test case I've added.
Comment 10 Egidijus Vaisnora CLA 2011-07-04 10:07:26 EDT
I have been puzzled with your test case. While moving TRANSIENT object to another transaction, the old transaction still knows current object as detached object, even if the same object is in the state NEW but in different transaction... 

I think this corner case is open gate to  unexpected errors. What if I rollback previous transaction? Silently, object will be resurrected in rollbacked transaction with an old CDOID, while another transaction, which knows object as NEW, will get reference to CLEAN object. How does cross references should behavior on such "migrating" object. Does it mean we can get model graph mixed among different transaction?..
Comment 11 Egidijus Vaisnora CLA 2011-07-04 12:09:42 EDT
If we follow the same logic as rollback does (see comment 10) and consider that sharing object between transaction is "good", then I need to improve fix, which will ensure to bring object into conflict state (event if it is in different transaction).
Comment 12 Eike Stepper CLA 2011-07-04 13:31:41 EDT
You're right, it is a general problem that the CDOState is stored *in* a CDOObject and that the object can have only one state rather than one state per CDOView.
Comment 13 Egidijus Vaisnora CLA 2011-07-05 08:22:08 EDT
State per view doesn't solves common problem: two transactions will still reference the same EObject and this object will be target for modification from two transactions. 

What if we solve this corner case following: 
- if object is TRANSIENT, then ownership of object belongs to transaction, where it was detached (works my patch)
- if we attach this object to different transaction, then object is moved to NEW state and this must imply to destroy it's detachment state from previous transaction. Previous transaction needs to loose control over such object. Thus no object will be removed. For this case I will need to make improvement
Comment 14 Eike Stepper CLA 2011-07-06 03:28:43 EDT
(In reply to comment #13)
> What if we solve this corner case following: 
> - if object is TRANSIENT, then ownership of object belongs to transaction,
> where it was detached (works my patch)
> - if we attach this object to different transaction, then object is moved to
> NEW state and this must imply to destroy it's detachment state 

DETACHED? Hasn't it been TRANSIENT?

> from previous
> transaction. Previous transaction needs to loose control over such object. 

Would that imply to keep the view pointer for such TRANSIENT objects?

> Thus no object will be removed. For this case I will need to make improvement
Comment 15 Egidijus Vaisnora CLA 2011-07-06 05:13:41 EDT
(In reply to comment #14)
> (In reply to comment #13)
> > What if we solve this corner case following: 
> > - if object is TRANSIENT, then ownership of object belongs to transaction,
> > where it was detached (works my patch)
> > - if we attach this object to different transaction, then object is moved to
> > NEW state and this must imply to destroy it's detachment state 
> 
> DETACHED? Hasn't it been TRANSIENT?

It is synonym. But here detachment state means a little bit more. Transaction still has references to this TRANSIENT object in object list and in save point as detached object. This is object state in transaction which must be destroyed after attaching object to different transaction. If we do not destroy this state, then old transaction will have control over object.

> 
> > from previous
> > transaction. Previous transaction needs to loose control over such object. 
> 
> Would that imply to keep the view pointer for such TRANSIENT objects?

Yes. Information about view is stored in revision, then perhaps some kind of TransientRevision, which shall store weak reference to view. Or maybe some kind of TRANSIENT object registry. Like WeakhashMap, where key-> object, value-> view 

> 
> > Thus no object will be removed. For this case I will need to make improvement
Comment 16 Eike Stepper CLA 2011-07-06 05:17:08 EDT
(In reply to comment #15)
> > Would that imply to keep the view pointer for such TRANSIENT objects?
> 
> Yes. Information about view is stored in revision, then perhaps some kind of
> TransientRevision, which shall store weak reference to view. Or maybe some kind
> of TRANSIENT object registry. Like WeakhashMap, where key-> object, value->
> view

You mean CDOObject, not CDORevision ;-)

Why not just use the view pointer in CDOObject?

How would legacy objects be dealt with?
Comment 17 Egidijus Vaisnora CLA 2011-07-08 07:08:53 EDT
(In reply to comment #16)
> You mean CDOObject, not CDORevision ;-)

Yes 

> Why not just use the view pointer in CDOObject?

Yes, and it should be weak reference
 
> How would legacy objects be dealt with?

Legacy elements has CDOLegacyWrapper adapter, which holds ref to CDO view. If legacy element doesn't loose this adapter during detach, when it should work
Comment 18 Egidijus Vaisnora CLA 2011-07-11 10:59:57 EDT
Created attachment 199418 [details]
patch v3

Where were few places, where was checking cdoView == null assuming that it shows transient object. Now seems to be fixed. Both test cases are covered.
Left to make server side checking for stale version commit, hold view by weak referene in CDOObject and rework previous patch with idea that TRANSIENT object has reference to transaction
Even it is not final patch, feel free to check, if it is going to right direction :)
Comment 19 Egidijus Vaisnora CLA 2011-07-16 06:06:49 EDT
Created attachment 199781 [details]
Patch v3

Fixed AbstractConflictResolver to tolerate objects without ID
Comment 20 Eike Stepper CLA 2011-09-25 09:43:22 EDT
Any action pending here?
Comment 21 Egidijus Vaisnora CLA 2011-09-26 02:30:59 EDT
At current time I stuck with other work, but I think, I will return back to this after ~2 weeks
Comment 22 Egidijus Vaisnora CLA 2012-01-11 10:51:43 EST
Committed changes to bugs/350120 branch
Comment 23 Eike Stepper CLA 2012-03-20 03:35:52 EDT
Just to be sure, am I supposed to review patch v3 or the tip of bugs/350120?
Comment 24 Eike Stepper CLA 2012-08-14 22:50:37 EDT
Moving all open issues to 4.2. Open bugs can be ported to 4.1 maintenance after they've been fixed in master.
Comment 25 Eike Stepper CLA 2013-06-29 12:16:15 EDT
We'll try to address open problems in 4.3 (master) first and then port fixes back to 4.2.
Comment 26 Eike Stepper CLA 2015-07-14 02:07:55 EDT
Moving all open bugzillas to 4.5.
Comment 27 Eike Stepper CLA 2016-07-31 00:50:45 EDT
Moving all unaddressed bugzillas to 4.6.
Comment 28 Eike Stepper CLA 2017-12-28 01:15:00 EST
Moving all open bugs to 4.7
Comment 29 Eike Stepper CLA 2019-11-08 02:07:25 EST
Moving all unresolved issues to version 4.8-
Comment 30 Eike Stepper CLA 2019-12-13 12:51:36 EST
Moving all unresolved issues to version 4.9
Comment 31 Eike Stepper CLA 2020-12-11 10:41:28 EST
Moving to 4.13.