Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [CDO] Is CDOMergingConflictResolver really called back when conflicts occur ?
[CDO] Is CDOMergingConflictResolver really called back when conflicts occur ? [message #1471189] Wed, 12 November 2014 23:50 Go to next message
Stephane  fournier is currently offline Stephane fournierFriend
Messages: 340
Registered: July 2009
Senior Member
Hi,

I'm doing some tests with 2 CDO clients that do the same model changes : same attribute on a same object instance in a while loop :

while (true) {
company.setName("Test client[" + args[0] + "] " + UUIDGenerator.DEFAULT.generate());
System.out.println(company.getName());
try {
transaction.commit();
Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}
}

The model is the one defined in org.eclipse.emf.cdo.examples.company

I have registered CDOMergingConflictResolver in my transaction:
transaction.options().addConflictResolver(new CDOMergingConflictResolver());

If I put a breakpoint in CDOMergingConflictResolver.resolveConflicts(Set<CDOObject> conflicts), I failed to stop in (I'm in debug of course).

Nevertheless I got exceptions due to conflits:
org.eclipse.emf.cdo.util.CommitConflictException: Attempt by Transaction[62:1] to modify historical revision: CDORevisionDelta[Company@OID6:0v8 343 --> [CDOFeatureDelta[name, SET, value=Test client[2] _fmDrYGrFEeSXQuTOjw9uRg, oldValue=UNSPECIFIED]]]
at org.eclipse.emf.internal.cdo.transaction.CDOSingleTransactionStrategyImpl.commit(CDOSingleTransactionStrategyImpl.java:77)
at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.commitSynced(CDOTransactionImpl.java:1237)
at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.commit(CDOTransactionImpl.java:1206)
at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.commit(CDOTransactionImpl.java:1198)


Hence, I do not understand why this conflict resolver is not called back to get a chance to solve them.

Does anyone have an idea ?
Stephane.
Re: [CDO] Is CDOMergingConflictResolver really called back when conflicts occur ? [message #1471405 is a reply to message #1471189] Thu, 13 November 2014 04:05 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6682
Registered: July 2009
Senior Member
Hi Stephane,

It's probably best to set a breakpoint in CDOViewImpl.doInvalidate() to check if/how handleConflicts() is called when
your change notification from the server is processed.

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper


Am 13.11.2014 um 00:50 schrieb Stephane Fournier:
> Hi,
>
> I'm doing some tests with 2 CDO clients that do the same model changes : same attribute on a same object instance in a
> while loop :
>
> while (true) {
> company.setName("Test client[" + args[0] + "] " + UUIDGenerator.DEFAULT.generate());
> System.out.println(company.getName());
> try {
> transaction.commit();
> Thread.sleep(200);
> } catch (Exception e) {
> e.printStackTrace();
> }
> }
>
> The model is the one defined in org.eclipse.emf.cdo.examples.company
>
> I have registered CDOMergingConflictResolver in my transaction:
> transaction.options().addConflictResolver(new CDOMergingConflictResolver());
>
> If I put a breakpoint in CDOMergingConflictResolver.resolveConflicts(Set<CDOObject> conflicts), I failed to stop in
> (I'm in debug of course).
>
> Nevertheless I got exceptions due to conflits:
> org.eclipse.emf.cdo.util.CommitConflictException: Attempt by Transaction[62:1] to modify historical revision:
> CDORevisionDelta[Company@OID6:0v8 343 --> [CDOFeatureDelta[name, SET, value=Test client[2] _fmDrYGrFEeSXQuTOjw9uRg,
> oldValue=UNSPECIFIED]]]
> at
> org.eclipse.emf.internal.cdo.transaction.CDOSingleTransactionStrategyImpl.commit(CDOSingleTransactionStrategyImpl.java:77)
> at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.commitSynced(CDOTransactionImpl.java:1237)
> at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.commit(CDOTransactionImpl.java:1206)
> at org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl.commit(CDOTransactionImpl.java:1198)
>
>
> Hence, I do not understand why this conflict resolver is not called back to get a chance to solve them.
>
> Does anyone have an idea ?
> Stephane.
>


Re: [CDO] Is CDOMergingConflictResolver really called back when conflicts occur ? [message #1471714 is a reply to message #1471405] Thu, 13 November 2014 09:31 Go to previous messageGo to next message
Stephane  fournier is currently offline Stephane fournierFriend
Messages: 340
Registered: July 2009
Senior Member
Hi Eike,
I've done what you suggested.

I checked when conflicts is null as CDOMergingConflictResolver is an instanceof nonConflictAware implementor, it is called on method handleNonConflict.

But if conflicts is not null I don't reach the for loop where resolvers are called back:

for (CDOObject conflict: conflicts.keySet) {
....
}

It seems conflicts are not passed correclty here thus resolvers are not called back.

Do you have CDO Junit tests to make sure it is working as you expect ?

I have attached my snippet with this post.
To run it you may declare this App as an equinox app through extension.
You have to pass 1 or 2 as application argument. 1 means client 1 and 2 means client 2, it is to help understanding traces.

Stéphane.
  • Attachment: TestApp.java
    (Size: 6.03KB, Downloaded 133 times)
Re: [CDO] Is CDOMergingConflictResolver really called back when conflicts occur ? [message #1472484 is a reply to message #1471714] Thu, 13 November 2014 22:46 Go to previous messageGo to next message
Stephane  fournier is currently offline Stephane fournierFriend
Messages: 340
Registered: July 2009
Senior Member
Hi Eike,

I have debugged the situation and I know why the resolvers are not called back.
In fact, conflicts are always null in CDOViewImpl after doInvalidate(...) after the call to :

Map<CDOObject, Pair<CDORevision, CDORevisionDelta>> conflicts = invalidate(allChangedObjects, allDetachedObjects, deltas, revisionDeltas, detachedObjects);

Hence, I stepped in to try understanding why:
In this method:
When looping on allChangedObjects, one delta is created in my case for CDOObject Company OID6 (OID6 is mentioned by the CDORevisionDelta ) but when requesting CDOObject changedObject = objects.get(key.getID()); it returns null.
Indeed, in the field objects, I did not retrieve my object Company OID6.
Hence I did not enter in the if (changedObject != null) case >>> no conflict is created.

One thing is really surprising: my Company object is not in "objects" list, only some objects are there linked to the CDOResource path....


I would really appreciate if you can run the app I provided to reproduce.
By the way, I put a bug in the app if the resource is empty. You have to replace resource.getContents().get(0) by following lines:
...
List<EObject> contents = resource.getContents();
Company company = null;
if (contents.isEmpty()) {
company = CompanyFactory.eINSTANCE.createCompany();
contents.add(company);
transaction.commit();
} else {
company = (Company) contents.get(0);
}

....

Thanks for your Help,
Stéphane.

Re: [CDO] Is CDOMergingConflictResolver really called back when conflicts occur ? [message #1472683 is a reply to message #1471714] Fri, 14 November 2014 02:50 Go to previous messageGo to next message
Eike Stepper is currently offline Eike StepperFriend
Messages: 6682
Registered: July 2009
Senior Member
Am 13.11.2014 um 10:31 schrieb Stephane Fournier:
> Hi Eike,
> I've done what you suggested.
>
> I checked when conflicts is null as CDOMergingConflictResolver is an instanceof nonConflictAware implementor, it is called on method handleNonConflict.
>
> But if conflicts is not null I don't reach the for loop where resolvers are called back:
>
> for (CDOObject conflict: conflicts.keySet) {
> ...
> }
>
> It seems conflicts are not passed correclty here thus resolvers are not called back.
>
> Do you have CDO Junit tests to make sure it is working as you expect ?
Please have a look at these tests:

org.eclipse.emf.cdo.tests.ConflictResolverTest
org.eclipse.emf.cdo.tests.Bugzilla_396804_Test
org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_419574_Test
org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_430794_Test
org.eclipse.emf.cdo.tests.bugzilla.Bugzilla_419962_Test
org.eclipse.emf.cdo.tests.ConflictResolverExtendedTest

>
> I have attached my snippet with this post.
> To run it you may declare this App as an equinox app through extension.
> You have to pass 1 or 2 as application argument. 1 means client 1 and 2 means client 2, it is to help understanding traces.
It would be easier if you transform your test code into a class that extends AbstractCDOTest. It's also more
reproducible because our test framework takes care of repo management and many other things.

Cheers
/Eike

----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper


Re: [CDO] Is CDOMergingConflictResolver really called back when conflicts occur ? [message #1472984 is a reply to message #1472683] Fri, 14 November 2014 08:44 Go to previous messageGo to next message
Stephane  fournier is currently offline Stephane fournierFriend
Messages: 340
Registered: July 2009
Senior Member
Hi Eike,
Ok I will transfor mthe code to extend the class you mentionned.

Stéphane.
Re: [CDO] Is CDOMergingConflictResolver really called back when conflicts occur ? [message #1474955 is a reply to message #1472683] Sat, 15 November 2014 22:18 Go to previous messageGo to next message
Stephane  fournier is currently offline Stephane fournierFriend
Messages: 340
Registered: July 2009
Senior Member
Hi Eike,

I'm back to ConflictResolver business Smile

I have tested your ConflictResolver JUnit tests and that works fine.

The big difference between your tests and mine (if i'm not wrong) :
You are in the same JVM, aren't you ?

My test involves 3 JVM :
- one is the CDO Server as a mem store.
- one JVM for client 1
- one JVM for client 2

Another difference is : in your ConflictResolver test, you only commit the transaction 1, and check some assert for transaction 2. Am I right ?

My scenario test is : each client within a loop modifies a company's name in parallel.

Nevertheless, if create 2 sessions with one transaction each, in the same JVM, I did not reproduce the issue.

But with 2 real clients (running in separate JVM on the same computer as the server), I got the issue systematically.

May I ask you to import a "test project" in your workspace (attached to this post) to test it please ?
It is a plug-in with the source code + 2 launch config.
You only have to start a Mem Store in localhost:2036 with one repo named repo1 before running the 2 launch config.

In less than 5mn you could tell me if made a mistake or if there is a real issue Smile

It would be great if you can help me to figure out this issue.

Stéphane.

Re: [CDO] Is CDOMergingConflictResolver really called back when conflicts occur ? [message #1548077 is a reply to message #1474955] Mon, 05 January 2015 20:44 Go to previous messageGo to next message
Stephane  fournier is currently offline Stephane fournierFriend
Messages: 340
Registered: July 2009
Senior Member
Hi there,

I got no response after my last answer Crying or Very Sad

Does anyone have an idea why ConflictResolver is not working as expected with separate JVM (one per client) ?

I ran CDO JUnit tests about ConflitResolver, but all transactions are ran from the same JVM and with with multiples transactions within a same JVM do not behave as different JVM running one transaction.

I provided a simple project to be imported, in a workspace to reproduce the issue. Did you run it to reproduce or not the bug ?

Could you help me please ?

Stephane.
Re: [CDO] Is CDOMergingConflictResolver really called back when conflicts occur ? [message #1548189 is a reply to message #1548077] Mon, 05 January 2015 22:15 Go to previous message
Stephane  fournier is currently offline Stephane fournierFriend
Messages: 340
Registered: July 2009
Senior Member
Hi There,

I cleaned the code of my simple application to make sure it is understandable by others.

Now, I can see in debugging the CDOMergingConflictResolver is called in some cases but I still have LocalCommitConflictException.

If someone can run this projet and spend some times to understand why it failed to merge the changes.

Is it due to the pace of the changes (i.e 200ms, it was to enforce the conflicts) on the same structural feature ?

Thanks in advance,
Stéphane.

Previous Topic:.ecore, XMLResource IDs and Xtext Builder
Next Topic:XSD -> ECore; internal missmatch (auto-creation)
Goto Forum:
  


Current Time: Fri Mar 29 06:26:38 GMT 2024

Powered by FUDForum. Page generated in 0.04474 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top