From 8e7f2da78049dbaeb6b25d8abc58b80583b6c48e Mon Sep 17 00:00:00 2001 From: Tamas Borbas Date: Thu, 17 Sep 2020 16:16:22 +0200 Subject: [PATCH 1/4] #61 Synchronize action addition with the execution on prepared engine --- .../incquerylabs/v4md/ViatraQueryAdapter.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java index 6183010..3d7cfef 100644 --- a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java +++ b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java @@ -109,7 +109,9 @@ public Optional getInitializedEngine() { */ public void executeActionOnEngine(Consumer action) { if(action != null) { - initializationActions.add(action); + synchronized (this) { + initializationActions.add(action); + } } // we use initializeEngine instead of getInitializedEngine because the initializeEngine // executes the actions anyway while the other is just when the initialization is not complete @@ -124,11 +126,13 @@ private Optional initializeEngine() { isInitialized = engine.map(e -> { boolean thereWasException = false; try { - e.getBaseIndex().coalesceTraversals(() -> { - initializationActions.forEach(action -> action.accept(e)); - return null; - }); - initializationActions.clear(); + if(!initializationActions.isEmpty()) { + e.getBaseIndex().coalesceTraversals(() -> { + initializationActions.forEach(action -> action.accept(e)); + return null; + }); + initializationActions.clear(); + } notifiers = new Notifier[0]; } catch (InvocationTargetException ite) { // we can invalidate our engine because there is two option for this exception: @@ -144,6 +148,7 @@ private Optional initializeEngine() { return false; }); if(!isInitialized) { + engine.ifPresent(AdvancedViatraQueryEngine::dispose); engine = Optional.empty(); } } From be0a36ea87f9d128860781dc99aa51d8bae828ee Mon Sep 17 00:00:00 2001 From: Tamas Borbas Date: Thu, 17 Sep 2020 16:17:01 +0200 Subject: [PATCH 2/4] Increase v4md version --- com.incquerylabs.v4md/gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/com.incquerylabs.v4md/gradle.properties b/com.incquerylabs.v4md/gradle.properties index 7ca9083..3cb9b23 100644 --- a/com.incquerylabs.v4md/gradle.properties +++ b/com.incquerylabs.v4md/gradle.properties @@ -1,5 +1,5 @@ -version=2.4.1-SNAPSHOT -buildNumber=241010 +version=2.4.2-SNAPSHOT +buildNumber=242010 group=com.incquerylabs.v4md viatraVersion=2.4.1 deployUrl = "build/maven-repository" From facb241789e8ba2f4d73496f1a1145c65ae1c63f Mon Sep 17 00:00:00 2001 From: Tamas Borbas Date: Mon, 21 Sep 2020 17:20:31 +0200 Subject: [PATCH 3/4] #61 Apply synchronization on engine user methods instead of synchronizing them internally --- .../incquerylabs/v4md/ViatraQueryAdapter.java | 68 +++++++++---------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java index 3d7cfef..454f6e9 100644 --- a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java +++ b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java @@ -107,50 +107,46 @@ public Optional getInitializedEngine() { * @param action the operation which would like to use the initialized VIATRA engine - * the action should not throw an exception during execution */ - public void executeActionOnEngine(Consumer action) { + public synchronized void executeActionOnEngine(Consumer action) { if(action != null) { - synchronized (this) { - initializationActions.add(action); - } + initializationActions.add(action); } // we use initializeEngine instead of getInitializedEngine because the initializeEngine // executes the actions anyway while the other is just when the initialization is not complete initializeEngine(); } - private Optional initializeEngine() { - synchronized(this) { - if(!isInitialized && ProjectUtilities.isLoaded(project.getPrimaryProject())) { - engine = Optional.of(createQueryEngine(project, notifiers)); - } - isInitialized = engine.map(e -> { - boolean thereWasException = false; - try { - if(!initializationActions.isEmpty()) { - e.getBaseIndex().coalesceTraversals(() -> { - initializationActions.forEach(action -> action.accept(e)); - return null; - }); - initializationActions.clear(); - } - notifiers = new Notifier[0]; - } catch (InvocationTargetException ite) { - // we can invalidate our engine because there is two option for this exception: - // 1. an exception is thrown directly by the action (which is not supported) - // 2. the engine got tainted because of an internal error, making the engine unusable - LOGGER.error(MESSAGE_ENGINE_PREPARE_ACTION_ERROR, ite); - e.dispose(); - thereWasException = true; + private synchronized Optional initializeEngine() { + if(!isInitialized && ProjectUtilities.isLoaded(project.getPrimaryProject())) { + engine = Optional.of(createQueryEngine(project, notifiers)); + } + isInitialized = engine.map(e -> { + boolean thereWasException = false; + try { + if(!initializationActions.isEmpty()) { + e.getBaseIndex().coalesceTraversals(() -> { + initializationActions.forEach(action -> action.accept(e)); + return null; + }); + initializationActions.clear(); } - return !thereWasException; - }).orElseGet(() -> { - LOGGER.warn(MESSAGE_ENGINE_NOT_READY); - return false; - }); - if(!isInitialized) { - engine.ifPresent(AdvancedViatraQueryEngine::dispose); - engine = Optional.empty(); - } + notifiers = new Notifier[0]; + } catch (InvocationTargetException ite) { + // we can invalidate our engine because there is two option for this exception: + // 1. an exception is thrown directly by the action (which is not supported) + // 2. the engine got tainted because of an internal error, making the engine unusable + LOGGER.error(MESSAGE_ENGINE_PREPARE_ACTION_ERROR, ite); + e.dispose(); + thereWasException = true; + } + return !thereWasException; + }).orElseGet(() -> { + LOGGER.warn(MESSAGE_ENGINE_NOT_READY); + return false; + }); + if(!isInitialized) { + engine.ifPresent(AdvancedViatraQueryEngine::dispose); + engine = Optional.empty(); } return engine; } From 9e78649ba8994d2eab6d79777ded744a4af121f2 Mon Sep 17 00:00:00 2001 From: Tamas Borbas Date: Wed, 23 Sep 2020 08:39:12 +0200 Subject: [PATCH 4/4] #61 Synchronize all the engine user methods --- .../com/incquerylabs/v4md/ViatraQueryAdapter.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java index 454f6e9..c88a466 100644 --- a/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java +++ b/com.incquerylabs.v4md/src/main/com/incquerylabs/v4md/ViatraQueryAdapter.java @@ -77,7 +77,7 @@ public AdvancedViatraQueryEngine getEngine() { * @return the initialized engine * @throws ViatraQueryException if no query engine was initialized before and initialization failed */ - public AdvancedViatraQueryEngine getInitializedEngineChecked() { + public synchronized AdvancedViatraQueryEngine getInitializedEngineChecked() { return getInitializedEngine() .orElseThrow(() -> new ViatraQueryException(MESSAGE_ENGINE_NOT_READY, MESSAGE_ENGINE_NOT_READY)); @@ -92,7 +92,7 @@ public AdvancedViatraQueryEngine getInitializedEngineChecked() { * @see ViatraQueryAdapter#executeActionOnEngine(Consumer) * @see ViatraQueryAdapter#requireQueries(IQuerySpecification) */ - public Optional getInitializedEngine() { + public synchronized Optional getInitializedEngine() { if(!isInitialized) { initializeEngine(); } @@ -157,7 +157,7 @@ private synchronized Optional initializeEngine() { * * @param querySpecifications the initializable queries */ - public void requireQueries(IQuerySpecification... querySpecifications) { + public synchronized void requireQueries(IQuerySpecification... querySpecifications) { Consumer initializer = e -> { for (IQuerySpecification querySpecification : querySpecifications) { e.getMatcher(querySpecification); @@ -172,7 +172,7 @@ public void requireQueries(IQuerySpecification... querySpecifications) { * * @param queryGroups the initializable queries */ - public void requireQueries(IQueryGroup... queryGroups) { + public synchronized void requireQueries(IQueryGroup... queryGroups) { Consumer initializer = e -> { for (IQueryGroup queryGroup : queryGroups) { queryGroup.prepare(e); @@ -187,7 +187,7 @@ public void requireQueries(IQueryGroup... queryGroups) { * Note Calling this method disposes the engine without any validation; it is not expected to be called by clients. * @see #dispose(String) */ - public void dispose(){ + public synchronized void dispose(){ engine.ifPresent(AdvancedViatraQueryEngine::dispose); isInitialized = false; project.getPrimaryModel().eAdapters().remove(this); @@ -200,14 +200,14 @@ public void dispose(){ * list of known users; and if there are no other users remaining, it disposes * the engine itself. */ - public void dispose(String identifier) { + public synchronized void dispose(String identifier) { identifierMap.remove(Objects.requireNonNull(identifier, "Identifier must not be null")); if (engineDisposable && identifierMap.isEmpty()) { dispose(); } } - public void wipeEngine(){ + public synchronized void wipeEngine(){ engine.ifPresent(AdvancedViatraQueryEngine::wipe); }