|
Re: [CDO] Is CDOMergingConflictResolver really called back when conflicts occur ? [message #1471405 is a reply to message #1471189] |
Thu, 13 November 2014 04:05 |
|
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.
>
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 #1472484 is a reply to message #1471714] |
Thu, 13 November 2014 22:46 |
Stephane fournier 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 |
|
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
Cheers
/Eike
----
http://www.esc-net.de
http://thegordian.blogspot.com
http://twitter.com/eikestepper
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.04368 seconds