From 5367ba21911da1422e8e93946dd07f7b1c4e6ae8 Mon Sep 17 00:00:00 2001 From: Erwan Bousse Date: Mon, 17 Jul 2017 11:45:47 +0200 Subject: [PATCH 1/2] [AbstractEngine] Add new method startSynchronous without thread --- .../engine/core/AbstractExecutionEngine.java | 67 ++++++++++--------- .../api/core/IExecutionEngine.java | 4 +- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/framework/execution_framework/plugins/org.gemoc.executionframework.engine/src/org/gemoc/executionframework/engine/core/AbstractExecutionEngine.java b/framework/execution_framework/plugins/org.gemoc.executionframework.engine/src/org/gemoc/executionframework/engine/core/AbstractExecutionEngine.java index 461e7beb1..78e38c89e 100644 --- a/framework/execution_framework/plugins/org.gemoc.executionframework.engine/src/org/gemoc/executionframework/engine/core/AbstractExecutionEngine.java +++ b/framework/execution_framework/plugins/org.gemoc.executionframework.engine/src/org/gemoc/executionframework/engine/core/AbstractExecutionEngine.java @@ -310,45 +310,50 @@ public final void start() { if (!_started) { _started = true; Runnable r = new Runnable() { - @Override public void run() { - try { - notifyEngineAboutToStart(); - Activator.getDefault().gemocRunningEngineRegistry.registerEngine(getName(), AbstractExecutionEngine.this); - setEngineStatus(EngineStatus.RunStatus.Running); - beforeStart(); - notifyEngineStarted(); - try { - performStart(); - } finally { - // We always try to commit the last remaining - // transaction - commitCurrentTransaction(); - } - - } catch (EngineStoppedException stopException) { - // not really an error, simply print the stop exception - // message - Activator.getDefault().info("Engine stopped by the user : " + stopException.getMessage()); - - } catch (Throwable e) { - error = e; - e.printStackTrace(); - Activator.getDefault().error("Exception received " + e.getMessage() + ", stopping engine.", e); - } finally { - // make sure to notify the stop if this wasn't an - // external call to stop() that lead us here. - // ie. normal end of the mode execution - stop(); - Activator.getDefault().info("*** " + AbstractExecutionEngine.this.getName() + " stopped ***"); - } + startSynchronous(); } }; thread = new Thread(r, engineKindName() + " " + _executionContext.getRunConfiguration().getExecutedModelURI()); thread.start(); } } + + + @Override + public final void startSynchronous() { + try { + notifyEngineAboutToStart(); + Activator.getDefault().gemocRunningEngineRegistry.registerEngine(getName(), AbstractExecutionEngine.this); + setEngineStatus(EngineStatus.RunStatus.Running); + beforeStart(); + notifyEngineStarted(); + try { + performStart(); + } finally { + // We always try to commit the last remaining + // transaction + commitCurrentTransaction(); + } + + } catch (EngineStoppedException stopException) { + // not really an error, simply print the stop exception + // message + Activator.getDefault().info("Engine stopped by the user : " + stopException.getMessage()); + + } catch (Throwable e) { + error = e; + e.printStackTrace(); + Activator.getDefault().error("Exception received " + e.getMessage() + ", stopping engine.", e); + } finally { + // make sure to notify the stop if this wasn't an + // external call to stop() that lead us here. + // ie. normal end of the mode execution + stop(); + Activator.getDefault().info("*** " + AbstractExecutionEngine.this.getName() + " stopped ***"); + } + } @Override public final void stop() { diff --git a/framework/framework_commons/plugins/org.gemoc.xdsmlframework.api/src/org/gemoc/xdsmlframework/api/core/IExecutionEngine.java b/framework/framework_commons/plugins/org.gemoc.xdsmlframework.api/src/org/gemoc/xdsmlframework/api/core/IExecutionEngine.java index 54d4160b8..b14b568b3 100644 --- a/framework/framework_commons/plugins/org.gemoc.xdsmlframework.api/src/org/gemoc/xdsmlframework/api/core/IExecutionEngine.java +++ b/framework/framework_commons/plugins/org.gemoc.xdsmlframework.api/src/org/gemoc/xdsmlframework/api/core/IExecutionEngine.java @@ -44,10 +44,12 @@ public interface IExecutionEngine extends IDisposable { MSEOccurrence getCurrentMSEOccurrence(); /** - * Starts the {@link IExecutionEngine}. + * Starts the {@link IExecutionEngine} in a new thread (non-blocking). */ void start(); + void startSynchronous(); + /** * Asks the engine to stop */ From d8982a50c679cca10ee9d08d8d68c1742cf4fad5 Mon Sep 17 00:00:00 2001 From: Erwan Bousse Date: Mon, 17 Jul 2017 12:34:45 +0200 Subject: [PATCH 2/2] Remove files added by mistake when merging --- .../engine/core/AbstractExecutionEngine.java | 559 ------------------ .../api/core/IExecutionEngine.java | 129 ---- 2 files changed, 688 deletions(-) delete mode 100644 framework/execution_framework/plugins/org.gemoc.executionframework.engine/src/org/gemoc/executionframework/engine/core/AbstractExecutionEngine.java delete mode 100644 framework/framework_commons/plugins/org.gemoc.xdsmlframework.api/src/org/gemoc/xdsmlframework/api/core/IExecutionEngine.java diff --git a/framework/execution_framework/plugins/org.gemoc.executionframework.engine/src/org/gemoc/executionframework/engine/core/AbstractExecutionEngine.java b/framework/execution_framework/plugins/org.gemoc.executionframework.engine/src/org/gemoc/executionframework/engine/core/AbstractExecutionEngine.java deleted file mode 100644 index 78e38c89e..000000000 --- a/framework/execution_framework/plugins/org.gemoc.executionframework.engine/src/org/gemoc/executionframework/engine/core/AbstractExecutionEngine.java +++ /dev/null @@ -1,559 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 Inria and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Inria - initial API and implementation - *******************************************************************************/ -package org.gemoc.executionframework.engine.core; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.HashSet; -import java.util.Set; - -import org.eclipse.emf.ecore.resource.ResourceSet; -import org.eclipse.emf.transaction.RecordingCommand; -import org.eclipse.emf.transaction.RollbackException; -import org.eclipse.emf.transaction.TransactionalEditingDomain; -import org.eclipse.emf.transaction.impl.EMFCommandTransaction; -import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain; -import org.gemoc.executionframework.engine.Activator; -import org.gemoc.xdsmlframework.api.core.EngineStatus; -import org.gemoc.xdsmlframework.api.core.EngineStatus.RunStatus; -import org.gemoc.xdsmlframework.api.core.IDisposable; -import org.gemoc.xdsmlframework.api.core.IExecutionContext; -import org.gemoc.xdsmlframework.api.core.IExecutionEngine; -import org.gemoc.xdsmlframework.api.engine_addon.IEngineAddon; - -import fr.inria.diverse.trace.commons.model.trace.MSEOccurrence; -import fr.inria.diverse.trace.commons.model.trace.Step; - - - -/** - * Common implementation of {@link IExecutionEngine}. - * It provides the following services: - * - * This class is intended to be subclassed. - * @author Didier Vojtisek - * - */ -public abstract class AbstractExecutionEngine implements IExecutionEngine, IDisposable { - - private RunStatus _runningStatus = RunStatus.Initializing; - - protected EngineStatus engineStatus = new EngineStatus(); - - protected IExecutionContext _executionContext; - - protected boolean _started = false; - protected boolean _isStopped = false; - - public Thread thread; - public boolean stopOnAddonError = false; - public Throwable error = null; - protected InternalTransactionalEditingDomain editingDomain; - private EMFCommandTransaction currentTransaction; - private Deque> currentSteps = new ArrayDeque<>(); - - abstract protected void performStart(); - - abstract protected void performStop(); - - abstract protected void performInitialize(IExecutionContext executionContext); - - abstract protected void beforeStart(); - - abstract protected void finishDispose(); - - @Override - public final void initialize(IExecutionContext executionContext) { - if (executionContext == null) - throw new IllegalArgumentException("executionContext"); - _executionContext = executionContext; - this.editingDomain = getEditingDomain(executionContext.getResourceModel().getResourceSet()); - setEngineStatus(EngineStatus.RunStatus.Initializing); - performInitialize(executionContext); - }; - - /* - * (non-Javadoc) - * - * @see org.gemoc.executionframework.engine.core.IExecutionEngine# - * getExecutionContext() - */ - @Override - public final IExecutionContext getExecutionContext() { - return _executionContext; - } - - /* - * (non-Javadoc) - * - * @see - * org.gemoc.executionframework.engine.core.IExecutionEngine#getEngineStatus - * () - */ - @Override - public final EngineStatus getEngineStatus() { - return engineStatus; - } - - @Override - public final void dispose() { - - try { - stop(); - notifyEngineAboutToDispose(); - getExecutionContext().dispose(); - finishDispose(); - } finally { - Activator.getDefault().gemocRunningEngineRegistry.unregisterEngine(getName()); - } - } - - - - - public String getName() { - return engineKindName() + " " + _executionContext.getRunConfiguration().getExecutedModelURI(); - } - - private void addonError(IEngineAddon addon, Exception e) { - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - String exceptionAsString = sw.toString(); - Activator.getDefault().error("Exception in Addon (" + addon + "), " + exceptionAsString, e); - if (stopOnAddonError) { - throw new RuntimeException(e); - } - } - - protected void notifyEngineAboutToStart() { - for (IEngineAddon addon : getExecutionContext().getExecutionPlatform().getEngineAddons()) { - try { - addon.engineAboutToStart(this); - } catch (Exception e) { - addonError(addon, e); - } - } - } - - protected void notifyEngineStarted() { - for (IEngineAddon addon : getExecutionContext().getExecutionPlatform().getEngineAddons()) { - try { - addon.engineStarted(this); - } catch (Exception e) { - addonError(addon, e); - } - } - } - - protected void notifyEngineInitialized() { - for (IEngineAddon addon : getExecutionContext().getExecutionPlatform().getEngineAddons()) { - try { - addon.engineInitialized(this); - } catch (Exception e) { - addonError(addon, e); - } - } - } - - protected final void notifyAboutToStop() { - for (IEngineAddon addon : getExecutionContext().getExecutionPlatform().getEngineAddons()) { - try { - addon.engineAboutToStop(this); - } catch (Exception e) { - addonError(addon, e); - } - } - } - - protected final void notifyEngineStopped() { - for (IEngineAddon addon : getExecutionContext().getExecutionPlatform().getEngineAddons()) { - try { - addon.engineStopped(this); - } catch (Exception e) { - addonError(addon, e); - } - } - } - - protected final void notifyEngineAboutToDispose() { - for (IEngineAddon addon : getExecutionContext().getExecutionPlatform().getEngineAddons()) { - try { - addon.engineAboutToDispose(this); - } catch (Exception e) { - addonError(addon, e); - } - } - } - - protected void notifyEngineStatusChanged(RunStatus newStatus) { - for (IEngineAddon addon : getExecutionContext().getExecutionPlatform().getEngineAddons()) { - try { - addon.engineStatusChanged(this, newStatus); - } catch (Exception e) { - addonError(addon, e); - } - } - } - - protected void notifyAboutToExecuteLogicalStep(Step l) { - for (IEngineAddon addon : getExecutionContext().getExecutionPlatform().getEngineAddons()) { - try { - addon.aboutToExecuteStep(this, l); - } catch (EngineStoppedException ese) { - Activator.getDefault().debug("Addon (" + addon.getClass().getSimpleName() + "@" + addon.hashCode() + ") has received stop command with message : " + ese.getMessage()); - stop(); - throw ese; // do not continue to execute anything, forward - // exception - } catch (Exception e) { - addonError(addon, e); - } - } - } - - protected void notifyLogicalStepExecuted(Step l) { - for (IEngineAddon addon : getExecutionContext().getExecutionPlatform().getEngineAddons()) { - try { - addon.stepExecuted(this, l); - } catch (EngineStoppedException ese) { - Activator.getDefault().debug("Addon (" + addon.getClass().getSimpleName() + "@" + addon.hashCode() + ") has received stop command with message : " + ese.getMessage()); - stop(); - } catch (Exception e) { - addonError(addon, e); - } - } - } - - /* - * (non-Javadoc) - * - * @see - * org.gemoc.executionframework.engine.core.IExecutionEngine#hasAddon(java. - * lang.Class) - */ - @Override - public final boolean hasAddon(Class type) { - for (IEngineAddon c : getExecutionContext().getExecutionPlatform().getEngineAddons()) { - if (c.getClass().equals(type)) - return true; - } - return false; - } - - /* - * (non-Javadoc) - * - * @see - * org.gemoc.executionframework.engine.core.IExecutionEngine#getAddon(java. - * lang.Class) - */ - @SuppressWarnings("unchecked") - @Override - public final T getAddon(Class type) { - for (IEngineAddon c : getExecutionContext().getExecutionPlatform().getEngineAddons()) { - if (c.getClass().equals(type)) - return (T) c; - } - return null; - } - - /* - * (non-Javadoc) - * - * @see org.gemoc.executionframework.engine.core.IExecutionEngine# - * getAddonsTypedBy(java.lang.Class) - */ - @SuppressWarnings("unchecked") - @Override - public final Set getAddonsTypedBy(Class type) { - Set result = new HashSet(); - for (IEngineAddon c : getExecutionContext().getExecutionPlatform().getEngineAddons()) { - if (type.isAssignableFrom(c.getClass())) - result.add((T) c); - } - return result; - } - - public final void setEngineStatus(RunStatus newStatus) { - _runningStatus = newStatus; - notifyEngineStatusChanged(newStatus); - } - - @Override - public final RunStatus getRunningStatus() { - return _runningStatus; - } - - public final void joinThread() { - try { - thread.join(); - } catch (InterruptedException e) { - Activator.getDefault().warn("InterruptedException received", e); - } - } - - @Override - public final void start() { - if (!_started) { - _started = true; - Runnable r = new Runnable() { - @Override - public void run() { - startSynchronous(); - } - }; - thread = new Thread(r, engineKindName() + " " + _executionContext.getRunConfiguration().getExecutedModelURI()); - thread.start(); - } - } - - - @Override - public final void startSynchronous() { - try { - notifyEngineAboutToStart(); - Activator.getDefault().gemocRunningEngineRegistry.registerEngine(getName(), AbstractExecutionEngine.this); - setEngineStatus(EngineStatus.RunStatus.Running); - beforeStart(); - notifyEngineStarted(); - try { - performStart(); - } finally { - // We always try to commit the last remaining - // transaction - commitCurrentTransaction(); - } - - } catch (EngineStoppedException stopException) { - // not really an error, simply print the stop exception - // message - Activator.getDefault().info("Engine stopped by the user : " + stopException.getMessage()); - - } catch (Throwable e) { - error = e; - e.printStackTrace(); - Activator.getDefault().error("Exception received " + e.getMessage() + ", stopping engine.", e); - } finally { - // make sure to notify the stop if this wasn't an - // external call to stop() that lead us here. - // ie. normal end of the mode execution - stop(); - Activator.getDefault().info("*** " + AbstractExecutionEngine.this.getName() + " stopped ***"); - } - } - - @Override - public final void stop() { - if (!_isStopped) { - notifyAboutToStop(); - _isStopped = true; - performStop(); - setEngineStatus(RunStatus.Stopped); - notifyEngineStopped(); - } - } - - private void cleanCurrentTransactionCommand() { - if (currentTransaction != null && currentTransaction.getCommand() != null) - currentTransaction.getCommand().dispose(); - } - - private void commitCurrentTransaction() { - if (currentTransaction != null) { - try { - currentTransaction.commit(); - } catch (RollbackException t) { - - cleanCurrentTransactionCommand(); - - // Extracting the real error from the RollbackException - Throwable realT = t.getStatus().getException(); - - // And we put it inside our own sort of exception, as a cause - SequentialExecutionException enclosingException = new SequentialExecutionException(getCurrentMSEOccurrence(), realT); - enclosingException.initCause(realT); - throw enclosingException; - } - currentTransaction = null; - } - } - - @Override - public final Deque getCurrentStack() { - Deque result = new ArrayDeque(); - for (Step ls : currentSteps) { - result.add(ls.getMseoccurrence()); - } - return result; - } - - private EMFCommandTransaction createTransaction(InternalTransactionalEditingDomain editingDomain, RecordingCommand command) { - return new EMFCommandTransaction(command, editingDomain, null); - } - - - /* (non-Javadoc) - * @see org.gemoc.xdsmlframework.api.core.IExecutionEngine#getCurrentMSEOccurrence() - */ - @Override - public final MSEOccurrence getCurrentMSEOccurrence() { - if (currentSteps.size() > 0) - return currentSteps.getFirst().getMseoccurrence(); - else - return null; - } - - private void startNewTransaction(InternalTransactionalEditingDomain editingDomain, RecordingCommand command) { - currentTransaction = createTransaction(editingDomain, command); - try { - currentTransaction.start(); - } catch (InterruptedException e) { - cleanCurrentTransactionCommand(); - command.dispose(); - SequentialExecutionException enclosingException = new SequentialExecutionException(getCurrentMSEOccurrence(), e); - enclosingException.initCause(e); - throw enclosingException; - } - } - - protected final void stopExecutionIfAsked() { - // If the engine is stopped, we use this call to stop the execution - if (_isStopped) { - // notification occurs only if not already stopped - notifyAboutToStop(); - throw new EngineStoppedException("Execution stopped."); - } - } - - protected final void beforeExecutionStep(Step step) { - - // We will trick the transaction with an empty command. This most - // probably make rollbacks impossible, but at least we can manage - // transactions the way we want. - RecordingCommand rc = new RecordingCommand(editingDomain) { - @Override - protected void doExecute() { - } - }; - - beforeExecutionStep(step, rc); - rc.execute(); - } - - /** - * To be called just after each execution step by an implementing engine. If - * the step was done through a RecordingCommand, it can be given. - */ - protected final void beforeExecutionStep(Step step, RecordingCommand rc) { - - try { - - currentSteps.push(step); - - stopExecutionIfAsked(); - - // We end any running transaction - commitCurrentTransaction(); - - // We notify addons - notifyAboutToExecuteLogicalStep(step); - - // We start a new transaction - startNewTransaction(editingDomain, rc); - - } - - // In case of error, we dispose recording commands to be sure to remove - // notifiers - catch (Throwable t) { - cleanCurrentTransactionCommand(); - rc.dispose(); - throw t; - } - - } - - private boolean isInStep() { - - boolean containsNotNull = false; - - for (Step ls : currentSteps) { - if (ls != null && ls.getMseoccurrence() != null) { - containsNotNull = true; - break; - } - } - - return !currentSteps.isEmpty() && containsNotNull; - - } - - /** - * To be called just after each execution step by an implementing engine. - */ - protected void afterExecutionStep() { - - RecordingCommand emptyrc = null; - - try { - - Step step = currentSteps.pop(); - - // We commit the transaction (which might be a different one - // than the one created earlier, or null if two operations - // end successively) - commitCurrentTransaction(); - - // We notify addons that the step ended. - notifyLogicalStepExecuted(step); - - // If we are still in the middle of a step, we start a new - // transaction with an empty command (since we can't have command - // containing the remainder of the previous step), - if (isInStep()) { - emptyrc = new RecordingCommand(editingDomain) { - @Override - protected void doExecute() { - } - }; - startNewTransaction(editingDomain, emptyrc); - emptyrc.execute(); - } - engineStatus.incrementNbLogicalStepRun(); - - stopExecutionIfAsked(); - } - - // In case of error, we dispose recording commands to be sure to remove - // notifiers - catch (Throwable t) { - cleanCurrentTransactionCommand(); - if (emptyrc != null) - emptyrc.dispose(); - throw t; - } - - } - - private static InternalTransactionalEditingDomain getEditingDomain(ResourceSet rs) { - TransactionalEditingDomain edomain = org.eclipse.emf.transaction.TransactionalEditingDomain.Factory.INSTANCE.getEditingDomain(rs); - if (edomain instanceof InternalTransactionalEditingDomain) - return (InternalTransactionalEditingDomain) edomain; - else - return null; - } - -} diff --git a/framework/framework_commons/plugins/org.gemoc.xdsmlframework.api/src/org/gemoc/xdsmlframework/api/core/IExecutionEngine.java b/framework/framework_commons/plugins/org.gemoc.xdsmlframework.api/src/org/gemoc/xdsmlframework/api/core/IExecutionEngine.java deleted file mode 100644 index b14b568b3..000000000 --- a/framework/framework_commons/plugins/org.gemoc.xdsmlframework.api/src/org/gemoc/xdsmlframework/api/core/IExecutionEngine.java +++ /dev/null @@ -1,129 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 Inria and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * Inria - initial API and implementation - *******************************************************************************/ -package org.gemoc.xdsmlframework.api.core; - -import java.util.Deque; -import java.util.Set; - -import org.gemoc.xdsmlframework.api.core.EngineStatus.RunStatus; -import org.gemoc.xdsmlframework.api.engine_addon.IEngineAddon; - -import fr.inria.diverse.trace.commons.model.launchconfiguration.LaunchConfiguration; -import fr.inria.diverse.trace.commons.model.trace.MSEOccurrence; - -/** - * The interface of the GEMOC Execution Engine. The Execution Engine is an - * entity able to execute models conforming to an xDSML as defined in the GEMOC - * ANR INS project. This API allows the caller to initialize the engine for a - * given model, and to run the engine in different ways. It also allows the - * caller to influence the constraints of the MoC at runtime. - * - * @author Didier Vojtisek - * - */ -public interface IExecutionEngine extends IDisposable { - - /** - * In case of nested calls, indicate the current stack of model specific event occurrences. - * @return the current stack of {@link MSEOccurrence} - */ - Deque getCurrentStack(); - - /** - * Provides the model specific event occurrence of the current step - * @return the current MSEOccurrence - */ - MSEOccurrence getCurrentMSEOccurrence(); - - /** - * Starts the {@link IExecutionEngine} in a new thread (non-blocking). - */ - void start(); - - void startSynchronous(); - - /** - * Asks the engine to stop - */ - void stop(); - - /** - * indicates the engine status {@link EngineStatus} - * @return the engine status - */ - EngineStatus getEngineStatus(); - - /** - * set the engine status {@link EngineStatus} - * @param status the new status - */ - void setEngineStatus(RunStatus status); - - /** - * Indicates if an {@link IEngineAddon} of the given type is linked to the engine - * @param type of the searched addon - * @return true if the engine has the addon, false otherwise. - */ - boolean hasAddon(Class type); - - /** - * get the first {@link IEngineAddon} of the required type associated to this engine. - * @param type searched type - * @return The {@link IEngineAddon} of the given type if it exists. - */ - T getAddon(Class type); - - /** - * get the execution context - * @return the {@link IExecutionContext} - */ - IExecutionContext getExecutionContext(); - - /** - * get the run status - * @return the {@link RunStatus} - */ - RunStatus getRunningStatus(); - - /** - * get all the {@link IEngineAddon} of the required type associated to this engine. - * @param type searched type - * @return a set of {@link IEngineAddon} of the given type. - */ - Set getAddonsTypedBy(Class type); - - /** - * Ask the engine to initialize - * @param executionContext the {@link IExecutionContext} - */ - void initialize(IExecutionContext executionContext); - - /** - * Create a {@link LaunchConfiguration} for the Trace based on the engine RunConfiguration. - * @return a {@link fr.inria.diverse.trace.commons.model.trace.LaunchConfiguration} - */ - default LaunchConfiguration extractLaunchConfiguration() { - return null; - } - - /** - * get the engine kind name - * @return a user display name for the engine kind (will be used to compute - * the full name of the engine instance) - */ - String engineKindName(); - - /** - * get the engine name - * @return a display name to identify this engine - */ - String getName(); -}