<!-- 
RSS generated by JIRA (8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d) at Wed Feb 07 19:55:54 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>OpenDaylight JIRA</title>
    <link>https://jira.opendaylight.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>8.20.10</version>
        <build-number>820010</build-number>
        <build-date>22-06-2022</build-date>
    </build-info>


<item>
            <title>[CONTROLLER-1578] Multi-threaded AbstractDataBrokerTest/s fail with TransactionCommitFailedException Caused by: java.lang.IllegalStateException: Store tree ... and candidate base ... differ.</title>
                <link>https://jira.opendaylight.org/browse/CONTROLLER-1578</link>
                <project id="10113" key="CONTROLLER">controller</project>
                    <description>&lt;p&gt;While working on the new style end2end component ElanServiceTest in (ongoing, WIP) &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/44000/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/44000/&lt;/a&gt;, I&apos;ve just hit the exception shown below.&lt;/p&gt;

&lt;p&gt;The test (currently local code, will push to c/44000 shortly) is really simple, it does a createElanInstance() on an IElanService in first @Test public void createElanInstance(), which works but the test then fails in the assert comparison due to another completely unrelated problem, so it quickly moves on to the next test, which does createElanInstance() again and then addElanInterface(), and that&apos;s what fails with below.&lt;/p&gt;

&lt;p&gt;This code itself is simple single threaded - but the elanmanager datatree listeners are async, of course... &lt;/p&gt;

&lt;p&gt;While I don&apos;t fully understand what&apos;s going on here yet, I suspect that perhaps one of the background threads processing from aysnc data store change listeners modified the data store concurrently and just before the Tx submit() in the addElanInterface() ?  &lt;/p&gt;

&lt;p&gt;Does the error below mean some sort of like optimistic lock violation?  Are we missing some sort of retry logic?  Do we have utilities for this?  Is this a problem particular to 1 line in elanmanager, or a more general issue that we need to properly retry data store write actions everywhere?&lt;/p&gt;

&lt;p&gt;java.lang.RuntimeException: TransactionCommitFailedException&lt;/p&gt;
{message=commit execution failed, errorList=[RpcError [message=commit execution failed, severity=ERROR, errorType=APPLICATION, tag=operation-failed, applicationTag=null, info=null, cause=java.lang.IllegalStateException: Store tree org.opendaylight.yangtools.yang.data.api.schema.tree.spi.MaterializedContainerNode@5243d730 and candidate base org.opendaylight.yangtools.yang.data.api.schema.tree.spi.MaterializedContainerNode@45b2d17b differ.]]}
&lt;p&gt;	at org.opendaylight.genius.mdsalutil.MDSALUtil.syncWrite(MDSALUtil.java:536)&lt;br/&gt;
	at org.opendaylight.netvirt.elan.internal.ElanServiceProvider.addElanInterface(ElanServiceProvider.java:277)&lt;br/&gt;
	at org.opendaylight.netvirt.elanmanager.tests.ElanServiceTest.addElanInterface(ElanServiceTest.java:80)&lt;br/&gt;
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)&lt;br/&gt;
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)&lt;br/&gt;
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)&lt;br/&gt;
	at java.lang.reflect.Method.invoke(Method.java:498)&lt;br/&gt;
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)&lt;br/&gt;
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)&lt;br/&gt;
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)&lt;br/&gt;
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)&lt;br/&gt;
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)&lt;br/&gt;
	at org.opendaylight.infrautils.inject.guice.testutils.GuiceRule$1.evaluate(GuiceRule.java:83)&lt;br/&gt;
	at org.opendaylight.infrautils.testutils.RunUntilFailureRule$RunUntilFailureStatement.evaluate(RunUntilFailureRule.java:59)&lt;br/&gt;
	at org.opendaylight.infrautils.testutils.LogRule$1.evaluate(LogRule.java:45)&lt;br/&gt;
	at org.junit.rules.RunRules.evaluate(RunRules.java:20)&lt;br/&gt;
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)&lt;br/&gt;
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)&lt;br/&gt;
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)&lt;br/&gt;
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)&lt;br/&gt;
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)&lt;br/&gt;
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)&lt;br/&gt;
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)&lt;br/&gt;
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)&lt;br/&gt;
	at org.opendaylight.infrautils.testutils.RunUntilFailureClassRule$RunUntilFailureStatement.evaluate(RunUntilFailureClassRule.java:46)&lt;br/&gt;
	at org.junit.rules.RunRules.evaluate(RunRules.java:20)&lt;br/&gt;
	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)&lt;br/&gt;
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)&lt;br/&gt;
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)&lt;br/&gt;
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)&lt;br/&gt;
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)&lt;br/&gt;
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)&lt;br/&gt;
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)&lt;br/&gt;
Caused by: TransactionCommitFailedException&lt;/p&gt;
{message=commit execution failed, errorList=[RpcError [message=commit execution failed, severity=ERROR, errorType=APPLICATION, tag=operation-failed, applicationTag=null, info=null, cause=java.lang.IllegalStateException: Store tree org.opendaylight.yangtools.yang.data.api.schema.tree.spi.MaterializedContainerNode@5243d730 and candidate base org.opendaylight.yangtools.yang.data.api.schema.tree.spi.MaterializedContainerNode@45b2d17b differ.]]}
&lt;p&gt;	at org.opendaylight.controller.md.sal.dom.broker.impl.TransactionCommitFailedExceptionMapper.newWithCause(TransactionCommitFailedExceptionMapper.java:37)&lt;br/&gt;
	at org.opendaylight.controller.md.sal.dom.broker.impl.TransactionCommitFailedExceptionMapper.newWithCause(TransactionCommitFailedExceptionMapper.java:18)&lt;br/&gt;
	at org.opendaylight.yangtools.util.concurrent.ExceptionMapper.apply(ExceptionMapper.java:87)&lt;br/&gt;
	at org.opendaylight.yangtools.util.concurrent.ExceptionMapper.apply(ExceptionMapper.java:37)&lt;br/&gt;
	at org.opendaylight.yangtools.util.concurrent.MappingCheckedFuture.mapException(MappingCheckedFuture.java:60)&lt;br/&gt;
	at org.opendaylight.yangtools.util.concurrent.MappingCheckedFuture.wrapInExecutionException(MappingCheckedFuture.java:64)&lt;br/&gt;
	at org.opendaylight.yangtools.util.concurrent.MappingCheckedFuture.get(MappingCheckedFuture.java:77)&lt;br/&gt;
	at com.google.common.util.concurrent.AbstractCheckedFuture.checkedGet(AbstractCheckedFuture.java:78)&lt;br/&gt;
	at org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker.syncWrite(SingleTransactionDataBroker.java:178)&lt;br/&gt;
	at org.opendaylight.genius.mdsalutil.MDSALUtil.syncWrite(MDSALUtil.java:533)&lt;br/&gt;
	... 32 more&lt;br/&gt;
Caused by: java.lang.IllegalStateException: Store tree org.opendaylight.yangtools.yang.data.api.schema.tree.spi.MaterializedContainerNode@5243d730 and candidate base org.opendaylight.yangtools.yang.data.api.schema.tree.spi.MaterializedContainerNode@45b2d17b differ.&lt;br/&gt;
	at org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTree.commit(InMemoryDataTree.java:119)&lt;br/&gt;
	at org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStore.commit(InMemoryDOMDataStore.java:248)&lt;br/&gt;
	at org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMStoreThreePhaseCommitCohort.commit(InMemoryDOMStoreThreePhaseCommitCohort.java:105)&lt;br/&gt;
	at org.opendaylight.controller.md.sal.dom.broker.impl.CommitCoordinationTask.commitAll(CommitCoordinationTask.java:211)&lt;br/&gt;
	at org.opendaylight.controller.md.sal.dom.broker.impl.CommitCoordinationTask.commitBlocking(CommitCoordinationTask.java:186)&lt;br/&gt;
	at org.opendaylight.controller.md.sal.dom.broker.impl.CommitCoordinationTask.call(CommitCoordinationTask.java:65)&lt;br/&gt;
	at org.opendaylight.controller.md.sal.dom.broker.impl.CommitCoordinationTask.call(CommitCoordinationTask.java:29)&lt;br/&gt;
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)&lt;br/&gt;
	at com.google.common.util.concurrent.MoreExecutors$DirectExecutorService.execute(MoreExecutors.java:299)&lt;br/&gt;
	at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)&lt;br/&gt;
	at com.google.common.util.concurrent.AbstractListeningExecutorService.submit(AbstractListeningExecutorService.java:58)&lt;br/&gt;
	at org.opendaylight.controller.md.sal.dom.broker.impl.SerializedDOMDataBroker.submit(SerializedDOMDataBroker.java:70)&lt;br/&gt;
	at org.opendaylight.controller.md.sal.dom.broker.impl.DOMForwardedWriteTransaction.submit(DOMForwardedWriteTransaction.java:144)&lt;br/&gt;
	at org.opendaylight.controller.md.sal.binding.impl.AbstractWriteTransaction.doSubmit(AbstractWriteTransaction.java:134)&lt;br/&gt;
	at org.opendaylight.controller.md.sal.binding.impl.BindingDOMWriteTransactionAdapter.submit(BindingDOMWriteTransactionAdapter.java:83)&lt;br/&gt;
	... 34 more&lt;/p&gt;</description>
                <environment>&lt;p&gt;Operating System: All&lt;br/&gt;
Platform: All&lt;/p&gt;</environment>
        <key id="26132">CONTROLLER-1578</key>
            <summary>Multi-threaded AbstractDataBrokerTest/s fail with TransactionCommitFailedException Caused by: java.lang.IllegalStateException: Store tree ... and candidate base ... differ.</summary>
                <type id="10104" iconUrl="https://jira.opendaylight.org/secure/viewavatar?size=xsmall&amp;avatarId=10303&amp;avatarType=issuetype">Bug</type>
                                                <status id="5" iconUrl="https://jira.opendaylight.org/images/icons/statuses/resolved.png" description="A resolution has been taken, and it is awaiting verification by reporter. From here issues are either reopened, or are closed.">Resolved</status>
                    <statusCategory id="3" key="done" colorName="green"/>
                                    <resolution id="10000">Done</resolution>
                                        <assignee username="-1">Unassigned</assignee>
                                    <reporter username="vorburger">Michael Vorburger</reporter>
                        <labels>
                    </labels>
                <created>Fri, 13 Jan 2017 13:27:04 +0000</created>
                <updated>Tue, 25 Jul 2023 08:24:18 +0000</updated>
                            <resolved>Thu, 16 Feb 2017 16:23:37 +0000</resolved>
                                                                    <component>mdsal</component>
                        <due></due>
                            <votes>0</votes>
                                    <watches>3</watches>
                                                                                                                <comments>
                            <comment id="51698" author="vorburger" created="Fri, 13 Jan 2017 13:59:07 +0000"  >&lt;p&gt;Attachment bug7538_stacktrace.txt has been added with description: Stack trace, same as in bug&apos;s comment, but more readable in an attachment without line wrapping&lt;/p&gt;</comment>
                            <comment id="51685" author="vorburger" created="Fri, 13 Jan 2017 23:52:56 +0000"  >&lt;p&gt;I half suspected that perhaps this could be an issue more to do with the test setup, because the RunUntilFailureRule re-creates all services N times, which in real production would never happen.&lt;/p&gt;

&lt;p&gt;So I&apos;ve further simplified it, and removed much of the test infra (incl. e.g. TestableDataTreeChangeListenerModule) now reproduce this in a test which sets up things up only once, and then simply by doing createElanInstance() in a loop - it works N (13, 5, ..) times and the N+1&apos;th time you get this exception.&lt;/p&gt;

&lt;p&gt;With this simplified ElanServiceCreate100InstancesTest, we can demonstrate that this is some concurrency issue - if we comment out the body of ElanInstanceManager.add(), which is an AsyncDataTreeChangeListenerBase, then this &quot;TransactionCommitFailedException Caused by: java.lang.IllegalStateException: Store tree ... and candidate base ... differ.&quot; does not occur anymore, even if we loop 1000 times to do createElanInstance().&lt;/p&gt;

&lt;p&gt;See &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/50460/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/50460/&lt;/a&gt; for the reproducer (it will only consist of ElanServiceCreate100InstancesTest; all other classes of that change are about to go into master as part of &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/44000/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/44000/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;So what are we doing wrong that this is happening?&lt;/p&gt;</comment>
                            <comment id="51686" author="tpantelis" created="Thu, 2 Feb 2017 02:00:13 +0000"  >&lt;p&gt;The error means transactions are being committed concurrently. This is controlled by the ListeningExecutorService passed to the SerializedDOMDataBroker. The submitted transactions must be presented to the SerializedDOMDataBroker serially and not interleaved. The DataBrokerTestCustomizer passes in a calling thread executor via MoreExecutors.newDirectExecutorService(). This is fine as long as transactions are submitted transactions from one thread only as is normally done in tests and as is done by createElanInstance.&lt;/p&gt;

&lt;p&gt;The ElanServiceCreate100InstancesListener submits transactions from the notification callback. The notification of listeners is controlled by the ExecutorService passed to the InMemoryDOMDataStore. The test setup also uses MoreExecutors.newDirectExecutorService() which would seem to be OK since listeners are notified after commit completes. &lt;/p&gt;

&lt;p&gt;The issue is related to the choice of executors passed to the SerializedDOMDataBroker and InMemoryDOMDataStore. The bottom line is that using direct executors is problematic. The executor passed to the SerializedDOMDataBroker must be single-threaded unless transactions are only submitted serially by the test method. InMemoryDOMDataStore executor should also not be a direct executor (could be single-threaded or multi-threaded).&lt;/p&gt;

&lt;p&gt;Therefore I would suggest modifying the test setup to pass single-threaded executors and then see if the error occurs.&lt;/p&gt;</comment>
                            <comment id="51687" author="vorburger" created="Thu, 2 Feb 2017 21:31:17 +0000"  >&lt;p&gt;Copy/paste of private email exchange for future reference, this is from before Tom&apos;s comment above:&lt;/p&gt;

&lt;p&gt;I&apos;ve further &quot;dumbed down&quot; the situation into an example test that does very little now, I&apos;ve stripped all &quot;functional&quot; code related to genius elan, and can still reproduce it: So we have one main thread doing what you can see in &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/50460/3/vpnservice/elanmanager/elanmanager-impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/ElanServiceCreate100InstancesTest.java&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/50460/3/vpnservice/elanmanager/elanmanager-impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/ElanServiceCreate100InstancesTest.java&lt;/a&gt; - it basically creates an instance of some date.&lt;/p&gt;

&lt;p&gt;Then, in another thread in the background, see &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/50460/3/vpnservice/elanmanager/elanmanager-impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/ElanServiceCreate100InstancesListener.java&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/50460/3/vpnservice/elanmanager/elanmanager-impl/src/test/java/org/opendaylight/netvirt/elanmanager/tests/ElanServiceCreate100InstancesListener.java&lt;/a&gt;, which is a AsyncDataTreeChangeListenerBase (some genius thing I&apos;m not sure you&apos;re familiar with but basically some infra for async change listeners), it basically does a merge() on the data that was write()&apos;n above; but note that the instance merge is NOT the one passed to the listener, but a new one created.&lt;/p&gt;</comment>
                            <comment id="51688" author="vorburger" created="Thu, 2 Feb 2017 21:39:20 +0000"  >&lt;p&gt;&amp;gt; The executor passed to the SerializedDOMDataBroker must be single-threaded (...)&lt;br/&gt;
&amp;gt; InMemoryDOMDataStore executor should also not be a direct executor (could be&lt;br/&gt;
&amp;gt; single-threaded or multi-threaded).&lt;br/&gt;
&amp;gt; Therefore I would suggest modifying the test setup to pass&lt;br/&gt;
&amp;gt; single-threaded executors and then see if the error occurs.&lt;/p&gt;

&lt;p&gt;Yes, this did the trick; confirming!  Yu da man - once again; thank you so much for this tip.&lt;/p&gt;

&lt;p&gt;Actually I was already (surprisingly) close, I had started toying with those Executors under &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51307/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51307/&lt;/a&gt; yesterday, before getting your comment above, based on the hint you gave me verbally in the Kernel call 2 weeks ago, but initially (patch set 1) made the made mistake of using a newCachedThreadPool instead of a newSingleThreadExecutor - close, but the wrong choice! &lt;img class=&quot;emoticon&quot; src=&quot;https://jira.opendaylight.org/images/icons/emoticons/wink.png&quot; height=&quot;16&quot; width=&quot;16&quot; align=&quot;absmiddle&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;/p&gt;

&lt;p&gt;I&apos;ll clean up &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51307/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51307/&lt;/a&gt; to have it become a a fix for this ... let&apos;s communicate via code review on that Gerrit to try to wrap this up.&lt;/p&gt;</comment>
                            <comment id="51689" author="vorburger" created="Thu, 2 Feb 2017 21:48:17 +0000"  >&lt;p&gt;Moved bug from product netvirt to controller, as this turned out to really be an issue in what people refer to as AbstractDataBrokerTest infrastructure (which is in controller), and not something done wrong in the elanmanager related code in netvirt.&lt;/p&gt;</comment>
                            <comment id="51690" author="tpantelis" created="Thu, 2 Feb 2017 22:42:23 +0000"  >&lt;p&gt;(In reply to Michael Vorburger from comment #6)&lt;br/&gt;
&amp;gt; &amp;gt; The executor passed to the SerializedDOMDataBroker must be single-threaded (...)&lt;br/&gt;
&amp;gt; &amp;gt; InMemoryDOMDataStore executor should also not be a direct executor (could be&lt;br/&gt;
&amp;gt; &amp;gt; single-threaded or multi-threaded).&lt;br/&gt;
&amp;gt; &amp;gt; Therefore I would suggest modifying the test setup to pass&lt;br/&gt;
&amp;gt; &amp;gt; single-threaded executors and then see if the error occurs.&lt;br/&gt;
&amp;gt; &lt;br/&gt;
&amp;gt; Yes, this did the trick; confirming!  Yu da man - once again; thank you so&lt;br/&gt;
&amp;gt; much for this tip.&lt;br/&gt;
&amp;gt; &lt;br/&gt;
&amp;gt; Actually I was already (surprisingly) close, I had started toying with those&lt;br/&gt;
&amp;gt; Executors under &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51307/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51307/&lt;/a&gt; yesterday,&lt;br/&gt;
&amp;gt; before getting your comment above, based on the hint you gave me verbally in&lt;br/&gt;
&amp;gt; the Kernel call 2 weeks ago, but initially (patch set 1) made the made&lt;br/&gt;
&amp;gt; mistake of using a newCachedThreadPool instead of a newSingleThreadExecutor&lt;br/&gt;
&amp;gt; - close, but the wrong choice! &lt;img class=&quot;emoticon&quot; src=&quot;https://jira.opendaylight.org/images/icons/emoticons/wink.png&quot; height=&quot;16&quot; width=&quot;16&quot; align=&quot;absmiddle&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;&lt;br/&gt;
&amp;gt; &lt;br/&gt;
&amp;gt; I&apos;ll clean up &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51307/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51307/&lt;/a&gt; to have it&lt;br/&gt;
&amp;gt; become a a fix for this ... let&apos;s communicate via code review on that Gerrit&lt;br/&gt;
&amp;gt; to try to wrap this up.&lt;/p&gt;

&lt;p&gt;Cool!&lt;/p&gt;</comment>
                            <comment id="51691" author="vorburger" created="Thu, 2 Feb 2017 23:44:15 +0000"  >&lt;p&gt;&amp;gt; The executor passed to the SerializedDOMDataBroker must be single-threaded &lt;/p&gt;

&lt;p&gt;This part is what really did the trick, and what &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51307/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51307/&lt;/a&gt; fixes.&lt;/p&gt;

&lt;p&gt;&amp;gt; InMemoryDOMDataStore executor should also not be a direct executor&lt;br/&gt;
&amp;gt; (could be single-threaded or multi-threaded).&lt;/p&gt;

&lt;p&gt;This part is less trivial, and seems not to be directly related to fixing this (the original problem above gets fixed with changing only the executor passed to the SerializedDOMDataBroker and not doing anything about the InMemoryDOMDataStore executor).  Changing this causes 3 tests in controller to fail (and who knows where else?!), but I&apos;ve nevertheless opened 2-3 other new Gerrits to explore this (separately from above&apos;s c/51307, so that can go in independently ASAP):&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51370/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51370/&lt;/a&gt; - trivial clean-up (tests OK)&lt;/li&gt;
&lt;/ul&gt;


&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51371/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51371/&lt;/a&gt; - switches InMemoryDOMDataStore executor from current direct to single-threaded; but breaks some tests&lt;/li&gt;
&lt;/ul&gt;


&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51369/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51369/&lt;/a&gt; - also failing the same tests as above, switched to InMemoryDOMDataStoreFactory which instead of the current MoreExecutors.newDirectExecutorService uses SpecialExecutors.newBlockingBoundedFastThreadPool, which appears to be a home made (wow) concurrent util that&apos;s a hybrid between (normally) multi-threaded but (sometimes, quote: &quot;if the queue is full ... running them in the same thread as the caller&quot;) what looks like the equivalent of a direct executor &lt;span class=&quot;error&quot;&gt;&amp;#91;is this a good idea?&amp;#93;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
</comment>
                            <comment id="51692" author="tpantelis" created="Fri, 3 Feb 2017 03:52:41 +0000"  >&lt;p&gt;It might make sense to make the executors configurable. So by default use direct executors and override appropriately per test.&lt;/p&gt;</comment>
                            <comment id="51693" author="vorburger" created="Fri, 3 Feb 2017 10:24:15 +0000"  >&lt;p&gt;&amp;gt; make the executors configurable. &lt;/p&gt;

&lt;p&gt;FYI The executor passed to the SerializedDOMDataBroker is already configurable, by DataBrokerTestCustomizer&apos;s getCommitCoordinatorExecutor().&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51307/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51307/&lt;/a&gt; proposes to change DataBrokerTestCustomizer&apos;s getCommitCoordinatorExecutor() default from newDirectExecutorService() to newSingleThreadExecutor()&lt;/p&gt;

&lt;p&gt;This is because it seems to me that we can consider the default newDirectExecutorService() a &quot;bug&quot; - it means that one cannot directly use the AbstractDataBrokerTest in a multi-threaded test.&lt;/p&gt;

&lt;p&gt;As I said, changing this one (but not the InMemoryDOMDataStore executor; see below) seems to have no negative effect, all tests still pass; at least do in controller do, and those I wrote in netvirt and genius pass BETTER (without the problem shown above) with this change.  Therefore I would think this change of default is a Good Thing (TM) to do.&lt;/p&gt;


&lt;p&gt;&amp;gt; So by default use direct executors and override appropriately per test.&lt;/p&gt;

&lt;p&gt;Of course, if one KNOWS about all of this, one can already @Override getCommitCoordinatorExecutor() in a test, via a custom subclass of DataBrokerTestCustomizer, not AbstractDataBrokerTest.  The problem is that I doubt mere mortals know about these internal details - usually, one just wants to write functional tests against DataBroker, not spend days investigating the internal threading model of the test infrastructure (as I have here).&lt;/p&gt;

&lt;p&gt;If you object to the change of the default, would you like to -1 &lt;br/&gt;
&lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51307/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51307/&lt;/a&gt; ?  If you agree to the change of this default, would you like to +1 and merge c/51307 ?&lt;/p&gt;


&lt;p&gt;For the InMemoryDOMDataStore executor choice, we could make DataBrokerTestCustomizer, or even InMemoryDOMDataStoreFactory (thoughts where best?), more configurable.  But that&apos;s almost a peripheral orthogonal parallel discussion at this point - that part seems to have nothing to do with fixing this bug.&lt;/p&gt;</comment>
                            <comment id="51694" author="vorburger" created="Mon, 6 Feb 2017 12:58:16 +0000"  >&lt;p&gt;&lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51307/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51307/&lt;/a&gt; broke existing green test(s) in at least genius (org.opendaylight.genius.test.MdSalUtilTest) and netvirt &lt;img class=&quot;emoticon&quot; src=&quot;https://jira.opendaylight.org/images/icons/emoticons/help_16.png&quot; height=&quot;16&quot; width=&quot;16&quot; align=&quot;absmiddle&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;, possibly more widely.&lt;/p&gt;

&lt;p&gt;Thus reverting in &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51467/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51467/&lt;/a&gt; ...&lt;/p&gt;

&lt;p&gt;I&apos;ll propose a new change to controller to make this an option instead.&lt;/p&gt;</comment>
                            <comment id="51695" author="vorburger" created="Mon, 6 Feb 2017 23:31:39 +0000"  >&lt;p&gt;&amp;gt; &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51307/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51307/&lt;/a&gt; broke existing green test(s)&lt;/p&gt;

&lt;p&gt;FTR: Any such tests which this broke were technically strictly speaking wrong, as they made an assumption which the DataBroker API never guaranteed ... see e.g. &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51487/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51487/&lt;/a&gt; for an example how to fix such tests.&lt;/p&gt;

&lt;p&gt;&amp;gt; I&apos;ll propose a new change to controller to make this an option instead.&lt;/p&gt;

&lt;p&gt;==&amp;gt; &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51486/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51486/&lt;/a&gt;&lt;/p&gt;</comment>
                            <comment id="51696" author="vorburger" created="Tue, 7 Feb 2017 00:10:16 +0000"  >&lt;p&gt;&amp;gt; tests which this broke were technically strictly speaking wrong&lt;br/&gt;
&amp;gt; see e.g. &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51487/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51487/&lt;/a&gt;&lt;br/&gt;
&amp;gt; for an example how to fix such tests.&lt;/p&gt;

&lt;p&gt;as well as &lt;a href=&quot;https://git.opendaylight.org/gerrit/#/c/51490/&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://git.opendaylight.org/gerrit/#/c/51490/&lt;/a&gt;&lt;/p&gt;</comment>
                            <comment id="51697" author="vorburger" created="Thu, 16 Feb 2017 16:23:10 +0000"  >&lt;p&gt;Done&lt;/p&gt;</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10000">
                    <name>Blocks</name>
                                            <outwardlinks description="blocks">
                                        <issuelink>
            <issuekey id="19832">GENIUS-51</issuekey>
        </issuelink>
                            </outwardlinks>
                                                        </issuelinktype>
                            <issuelinktype id="10002">
                    <name>Duplicate</name>
                                                                <inwardlinks description="is duplicated by">
                                        <issuelink>
            <issuekey id="19832">GENIUS-51</issuekey>
        </issuelink>
                            </inwardlinks>
                                    </issuelinktype>
                    </issuelinks>
                <attachments>
                            <attachment id="13607" name="bug7538_stacktrace.txt" size="7032" author="vorburger" created="Fri, 13 Jan 2017 13:59:07 +0000"/>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                            <customfield id="customfield_11400" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                        <customfield id="customfield_10208" key="com.atlassian.jira.plugin.system.customfieldtypes:textfield">
                        <customfieldname>External issue ID</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>7538</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10201" key="com.atlassian.jira.plugin.system.customfieldtypes:url">
                        <customfieldname>External issue URL</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue><![CDATA[https://bugs.opendaylight.org/show_bug.cgi?id=7538]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                            <customfield id="customfield_10206" key="com.atlassian.jira.plugin.system.customfieldtypes:select">
                        <customfieldname>Issue Type</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="10300"><![CDATA[Bug]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_10204" key="com.atlassian.jira.plugin.system.customfieldtypes:select">
                        <customfieldname>ODL SR Target Milestone</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="10348"><![CDATA[Carbon-M5]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                        <customfield id="customfield_10202" key="com.atlassian.jira.plugin.system.customfieldtypes:select">
                        <customfieldname>Priority</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="10312"><![CDATA[High]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10000" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>0|i02rfr:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                </customfields>
    </item>
</channel>
</rss>