Concurrency in incquery [message #1352320] |
Tue, 13 May 2014 12:04 |
Balázs Grill Messages: 8 Registered: July 2009 |
Junior Member |
|
|
Hello,
We've been experiencing some problems since we switched to tag 0.8.0M3. When the incquery is accessed concurrently from multiple threads, it starts throwing exceptions and causes the whole workbench to freeze.
The situation is as follows:
Our models are contained in projects and there is a view which content is calculated using queries. When the user opens a project, a resourceSet is created, and a job is started to read its content. In the meantime, the view tries to initialize its content and instantiates its queries. The following is the first exception which occurs during initialization of the query:
Thread [main] (Suspended (exception ConcurrentModificationException))
owns: ReteBoundary (id=153)
owns: ReteEngine (id=154)
HashMap$EntryIterator(HashMap$HashIterator<E>).nextEntry() line: not available
HashMap$EntryIterator.next() line: not available
HashMap$EntryIterator.next() line: not available
StandardTable$Column$EntrySetIterator.computeNext() line: 620
StandardTable$Column$EntrySetIterator.computeNext() line: 615
StandardTable$Column$EntrySetIterator(AbstractIterator<T>).tryToComputeNext() line: 141
StandardTable$Column$EntrySetIterator(AbstractIterator<T>).hasNext() line: 136
NavigationHelperImpl.processAllFeatureInstances(EStructuralFeature, IEStructuralFeatureProcessor) line: 289
EMFPatternMatcherRuntimeContext.enumerateDirectBinaryEdgeInstances(Object, IPatternMatcherRuntimeContext$ModelElementPairCrawler) line: 125
EMFPatternMatcherRuntimeContext.enumerateAllBinaryEdgeInstances(Object, IPatternMatcherRuntimeContext$ModelElementPairCrawler) line: 137
ReferenceFeeder.feed() line: 36
ReteBoundary.accessBinaryEdgeRoot(Object) line: 254
ReteContainerCompiler.binaryEdgeTypePlan(Tuple, Object) line: 185
SubPlanProcessor.processConstraint(TypeBinary) line: 135
SubPlanProcessor.dispatchConstraint(EnumerablePConstraint) line: 86
SubPlanProcessor.processEnumerableConstraint(EnumerablePConstraint) line: 58
QuasiTreeLayout$Scaffold.run() line: 81
QuasiTreeLayout.layout(PBody, IOperationCompiler<?>, IPatternMatcherContext) line: 45
EPMBuildScaffold<Collector>.construct(PQuery) line: 53
EPMBuilder<Collector>.construct(PQuery) line: 54
ReteBoundary.construct(PQuery) line: 528
ReteBoundary.accessProduction(PQuery) line: 460
ReteContainerCompiler.patternCallPlan(Tuple, PQuery) line: 157
SubPlanProcessor.processConstraint(PositivePatternCall) line: 131
SubPlanProcessor.dispatchConstraint(EnumerablePConstraint) line: 84
SubPlanProcessor.processEnumerableConstraint(EnumerablePConstraint) line: 58
QuasiTreeLayout$Scaffold.run() line: 81
QuasiTreeLayout.layout(PBody, IOperationCompiler<?>, IPatternMatcherContext) line: 45
EPMBuildScaffold<Collector>.construct(PQuery) line: 53
EPMBuilder<Collector>.construct(PQuery) line: 54
ReteBoundary.construct(PQuery) line: 528
ReteBoundary.accessProduction(PQuery) line: 460
ReteEngine$1.call() line: 178
ReteEngine$1.call() line: 1
NavigationHelperImpl.coalesceTraversals(Callable<V>) line: 971
EMFPatternMatcherRuntimeContext.coalesceTraversals(Callable<V>) line: 86
ReteEngine.constructionWrapper(Callable<Void>) line: 226
ReteEngine.accessMatcher(PQuery) line: 174
ShortnamePathCollisionMatcher(BaseMatcher<Match>).accessMatcher(IncQueryEngineImpl, IQuerySpecification<BaseMatcher<Match>>) line: 71
ShortnamePathCollisionMatcher(BaseMatcher<Match>).<init>(IncQueryEngine, IQuerySpecification<BaseMatcher<Match>>) line: 60
generic.eiq line: 7
generic.eiq line: 7
generic.eiq line: 7
generic.eiq line: 7
ShortnamePathCollisionQuerySpecification(BaseQuerySpecification<Matcher>).getMatcher(IncQueryEngine) line: 68
IncQueryEventSource<Match>.<init>(IncQueryEventRealm, IncQueryEventSourceSpecification<Match>) line: 44
IncQueryEventRealm.createSource(EventSourceSpecification<Match>) line: 50
IncQueryRuleInstanceBuilder<Match>.prepareRuleInstance(RuleInstance<Match>, EventFilter<? super Match>) line: 34
RuleSpecification<EventAtom>.instantiateRule(EventRealm, EventFilter<? super EventAtom>) line: 85
RuleBase.instantiateRule(RuleSpecification<EventAtom>, EventFilter<? super EventAtom>) line: 78
ExecutionSchema(RuleEngine).addRule(RuleSpecification<EventAtom>, EventFilter<? super EventAtom>) line: 113
ObservableCollectionHelper.prepareRuleEngine(IncQueryEngine, RuleSpecification<Match>, EventFilter<Match>) line: 116
ObservablePatternMatchList<Match>.<init>(IQuerySpecification<Matcher>, IncQueryEngine) line: 84
IncQueryObservables.observeMatchesAsList(IQuerySpecification<Matcher>, IncQueryEngine) line: 84
When this happens, the worker thread is currently doing the on-load model traversal:
Thread [Worker-4] (Suspended)
BasicNotifierImpl$EAdapterList<E>.newData(int) line: 108
BasicNotifierImpl$EAdapterList<E>(BasicEList<E>).grow(int) line: 727
BasicNotifierImpl$EAdapterList<E>(BasicEList<E>).addUnique(E) line: 416
BasicNotifierImpl$EAdapterList<E>(AbstractEList<E>).add(E) line: 301
BasicNotifierImpl$EAdapterList<E>.add(E) line: 193
.
.
.
NavigationHelperContentAdapter(EContentAdapter).addAdapter(Notifier) line: 349
NavigationHelperContentAdapter.access$1(NavigationHelperContentAdapter, Notifier) line: 1
NavigationHelperContentAdapter$1.call() line: 297
NavigationHelperContentAdapter$1.call() line: 1
NavigationHelperImpl.coalesceTraversals(Callable<V>) line: 987
NavigationHelperContentAdapter.addAdapter(Notifier) line: 289
NavigationHelperContentAdapter(EContentAdapter).handleContainment(Notification) line: 139
NavigationHelperContentAdapter(EContentAdapter).selfAdapt(Notification) line: 63
NavigationHelperContentAdapter(EContentAdapter).notifyChanged(Notification) line: 40
NavigationHelperContentAdapter.notifyChanged(Notification) line: 201
ARResourceImpl(BasicNotifierImpl).eNotify(Notification) line: 374
ResourceImpl$ContentsEList<E>(NotifyingListImpl<E>).dispatchNotification(Notification) line: 261
ResourceImpl$ContentsEList<E>(NotifyingListImpl<E>).addUnique(E) line: 294
ResourceImpl$ContentsEList<E>(AbstractEList<E>).add(E) line: 301
ARLoad.load(XMLResource, InputStream, Map<?,?>) line: 38
ARResourceImpl(XMLResourceImpl).doLoad(InputStream, Map<?,?>) line: 253
ARResourceImpl(ResourceImpl).load(InputStream, Map<?,?>) line: 1518
ARResourceImpl(ResourceImpl).load(Map<?,?>) line: 1297
Does concurrent calls causes this? Do I need to take extra measures to avoid concurrent calls even when the model is written on one thread? Do I need to delay query initialization until the model is loaded?
Thanks in advance
Balázs Grill;
|
|
|
|
|
Re: Concurrency in incquery [message #1356621 is a reply to message #1356594] |
Thu, 15 May 2014 06:34 |
Abel Hegedus Messages: 197 Registered: September 2015 |
Senior Member |
|
|
The problem is that the query initialization uses an iterator on the index (see NavigationHelperImpl.processAllFeatureInstances(EStructuralFeature, IEStructuralFeatureProcessor) line: 289) to fill up the Rete network. In the same time, the load modifies the model and the notifications are handled by the index (see NavigationHelperContentAdapter.notifyChanged(Notification) line: 201) and as a result a new element is added to the collection that the iterator is using.
The short answer is yes, you have to either: initialize queries _before_ loading the resource or wait for the initialization after the load is finished.
[Edit:] You may encounter this now as in earlier versions the collection was copied instead of iterated. I'm not sure when the change happened.
[Updated on: Thu, 15 May 2014 06:37] by Moderator Report message to a moderator
|
|
|
|
Powered by
FUDForum. Page generated in 0.04950 seconds