tmf.core: Add failure causes to analyses
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / statesystem / TmfStateSystemAnalysisModule.java
index 83ab1ceecf8b459a14620ba7e62fb31cb0ae8414..4a688bd97770f4cf4dd0a9777a1451327a045acf 100644 (file)
 
 package org.eclipse.tracecompass.tmf.core.statesystem;
 
-import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
-
 import java.io.File;
 import java.io.IOException;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 
@@ -39,7 +36,6 @@ import org.eclipse.tracecompass.statesystem.core.backend.StateHistoryBackendFact
 import org.eclipse.tracecompass.tmf.core.analysis.TmfAbstractAnalysisModule;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
 import org.eclipse.tracecompass.tmf.core.exceptions.TmfTraceException;
-import org.eclipse.tracecompass.tmf.core.project.model.ITmfPropertiesProvider;
 import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest;
 import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
@@ -51,6 +47,8 @@ import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils;
 import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
 
+import com.google.common.annotations.VisibleForTesting;
+
 /**
  * Abstract analysis module to generate a state system. It is a base class that
  * can be used as a shortcut by analysis who just need to build a single state
@@ -63,20 +61,21 @@ import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment;
  * @author Geneviève Bastien
  */
 public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisModule
-        implements ITmfAnalysisModuleWithStateSystems, ITmfPropertiesProvider {
+        implements ITmfAnalysisModuleWithStateSystems {
 
     private static final String EXTENSION = ".ht"; //$NON-NLS-1$
 
     private final CountDownLatch fInitialized = new CountDownLatch(1);
     private final Object fRequestSyncObj = new Object();
 
-    @Nullable private ITmfStateSystemBuilder fStateSystem;
-    @Nullable private ITmfStateProvider fStateProvider;
-    @Nullable private IStateHistoryBackend fHtBackend;
-    @Nullable private ITmfEventRequest fRequest;
-    @Nullable private TmfTimeRange fTimeRange = null;
+    private @Nullable ITmfStateSystemBuilder fStateSystem;
+    private @Nullable ITmfEventRequest fRequest;
+    private @Nullable TmfTimeRange fTimeRange = null;
 
     private int fNbRead = 0;
+    private boolean fInitializationSucceeded;
+
+    private volatile @Nullable ITmfStateProvider fStateProvider;
 
     /**
      * State system backend types
@@ -105,7 +104,8 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
      *            The trace for which you want the state system
      * @param moduleId
      *            The ID of the state system analysis module
-     * @return The state system, or null if there was no match
+     * @return The state system, or null if there was no match or the module was
+     *         not initialized correctly
      */
     public static @Nullable ITmfStateSystem getStateSystem(ITmfTrace trace, String moduleId) {
         TmfStateSystemAnalysisModule module =
@@ -117,8 +117,7 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
             }
             IStatus status = module.schedule();
             if (status.isOK()) {
-                module.waitForInitialization();
-                return module.getStateSystem();
+                return module.waitForInitialization() ? module.getStateSystem() : null;
             }
         }
         return null;
@@ -163,21 +162,43 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
     }
 
     /**
-     * Block the calling thread until the analysis module has been initialized.
-     * After this method returns, {@link #getStateSystem()} should not return
-     * null anymore.
+     * @since 2.0
      */
-    public void waitForInitialization() {
+    @Override
+    public boolean waitForInitialization() {
         try {
             fInitialized.await();
-        } catch (InterruptedException e) {}
+        } catch (InterruptedException e) {
+            return false;
+        }
+        return fInitializationSucceeded;
+    }
+
+    /**
+     * @since 2.0
+     */
+    @Override
+    public boolean isQueryable(long ts) {
+        /* Return true if there is no state provider available (the analysis is not being built) */
+        ITmfStateProvider provider = fStateProvider;
+        if (provider == null) {
+            return true;
+        }
+        return ts <= provider.getLatestSafeTime();
     }
 
     // ------------------------------------------------------------------------
     // TmfAbstractAnalysisModule
     // ------------------------------------------------------------------------
 
-    private @Nullable File getSsFile() {
+    /**
+     * Get the file where to save the results of the analysis
+     *
+     * @return The file to save the results in
+     * @since 2.3
+     */
+    @VisibleForTesting
+    protected @Nullable File getSsFile() {
         ITmfTrace trace = getTrace();
         if (trace == null) {
             return null;
@@ -199,11 +220,10 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
             /* Get the state system according to backend */
             StateSystemBackendType backend = getBackendType();
 
-
             ITmfTrace trace = getTrace();
             if (trace == null) {
                 // Analysis was cancelled in the meantime
-                fInitialized.countDown();
+                analysisReady(false);
                 return false;
             }
             switch (backend) {
@@ -233,12 +253,25 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
                 break;
             }
         } catch (TmfTraceException e) {
-            fInitialized.countDown();
+            analysisReady(false);
             return false;
         }
         return !mon.isCanceled();
     }
 
+    /**
+     * Make the module available and set whether the initialization succeeded or
+     * not. If not, no state system is available and
+     * {@link #waitForInitialization()} should return false.
+     *
+     * @param success
+     *            True if the initialization succeeded, false otherwise
+     */
+    private void analysisReady(boolean succeeded) {
+        fInitializationSucceeded = succeeded;
+        fInitialized.countDown();
+    }
+
     @Override
     protected void canceling() {
         ITmfEventRequest req = fRequest;
@@ -276,9 +309,8 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
             try {
                 IStateHistoryBackend backend = StateHistoryBackendFactory.createHistoryTreeBackendExistingFile(
                         id, htFile, version);
-                fHtBackend = backend;
                 fStateSystem = StateSystemFactory.newStateSystem(backend, false);
-                fInitialized.countDown();
+                analysisReady(true);
                 return;
             } catch (IOException e) {
                 /*
@@ -295,7 +327,6 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
         try {
             IStateHistoryBackend backend = StateHistoryBackendFactory.createHistoryTreeBackendNewFile(
                     id, htFile, provider.getVersion(), provider.getStartTime(), QUEUE_SIZE);
-            fHtBackend = backend;
             fStateSystem = StateSystemFactory.newStateSystem(backend);
             provider.assignTargetStateSystem(fStateSystem);
             build(provider);
@@ -376,7 +407,6 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
         provider.assignTargetStateSystem(realSS);
 
         /* 7 */
-        fHtBackend = partialBackend;
         fStateSystem = realSS;
 
         build(provider);
@@ -389,7 +419,6 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
      */
     private void createNullHistory(String id, ITmfStateProvider provider) {
         IStateHistoryBackend backend = StateHistoryBackendFactory.createNullBackend(id);
-        fHtBackend = backend;
         fStateSystem = StateSystemFactory.newStateSystem(backend);
         provider.assignTargetStateSystem(fStateSystem);
         build(provider);
@@ -402,7 +431,6 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
      */
     private void createInMemoryHistory(String id, ITmfStateProvider provider) {
         IStateHistoryBackend backend = StateHistoryBackendFactory.createInMemoryBackend(id, provider.getStartTime());
-        fHtBackend = backend;
         fStateSystem = StateSystemFactory.newStateSystem(backend);
         provider.assignTargetStateSystem(fStateSystem);
         build(provider);
@@ -413,13 +441,14 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
         if (provider != null) {
             provider.dispose();
         }
-        if (deleteFiles && (fHtBackend != null)) {
-            fHtBackend.removeFiles();
+        fStateProvider = null;
+        if (deleteFiles && (fStateSystem != null)) {
+            fStateSystem.removeFiles();
         }
     }
 
     private void build(ITmfStateProvider provider) {
-        if ((fStateSystem == null) || (fHtBackend == null)) {
+        if (fStateSystem == null) {
             throw new IllegalArgumentException();
         }
 
@@ -437,41 +466,65 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
         fStateProvider = provider;
         synchronized (fRequestSyncObj) {
             startRequest();
+            request = fRequest;
         }
 
         /*
          * The state system object is now created, we can consider this module
          * "initialized" (components can retrieve it and start doing queries).
          */
-        fInitialized.countDown();
+        analysisReady(true);
 
         /*
          * Block the executeAnalysis() construction is complete (so that the
          * progress monitor displays that it is running).
          */
         try {
-            if (fRequest != null) {
-                fRequest.waitForCompletion();
+            if (request != null) {
+                request.waitForCompletion();
+                if (request.isFailed()) {
+                    Throwable failureCause = request.getFailureCause();
+                    if (failureCause != null) {
+                        fail(failureCause);
+                    } else {
+                        fail(new RuntimeException("Event request failed without a cause")); //$NON-NLS-1$
+                    }
+                }
             }
         } catch (InterruptedException e) {
-             e.printStackTrace();
+             fail(e);
         }
     }
 
-    private class StateSystemEventRequest extends TmfEventRequest {
+    /**
+     * A request to build a state system from a state provider
+     *
+     * @since 2.3
+     */
+    @VisibleForTesting
+    protected class StateSystemEventRequest extends TmfEventRequest {
         private final ITmfStateProvider sci;
         private final ITmfTrace trace;
 
+        /**
+         * Constructor
+         *
+         * @param sp
+         *            The state provider used to build the state system
+         * @param timeRange
+         *            The requested time range for the request
+         * @param index
+         *            The event number at which to start the request
+         */
         public StateSystemEventRequest(ITmfStateProvider sp, TmfTimeRange timeRange, int index) {
             super(ITmfEvent.class,
                     timeRange,
                     index,
                     ITmfEventRequest.ALL_DATA,
-                    ITmfEventRequest.ExecutionType.BACKGROUND);
+                    ITmfEventRequest.ExecutionType.BACKGROUND,
+                    TmfStateSystemAnalysisModule.this.getDependencyLevel());
             this.sci = sp;
-
-            // sci.getTrace() will eventually return a @NonNull
-            trace = checkNotNull(sci.getTrace());
+            trace = sci.getTrace();
 
         }
 
@@ -514,9 +567,7 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
         @Override
         public void handleCancel() {
             super.handleCancel();
-            if (isCompleteTrace(trace)) {
-                disposeProvider(true);
-            }
+            disposeProvider(true);
         }
 
         @Override
@@ -573,11 +624,28 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
         if (stateProvider == null || timeRange == null) {
             return;
         }
-        ITmfEventRequest request = new StateSystemEventRequest(stateProvider, timeRange, fNbRead);
+        ITmfEventRequest request = createEventRequest(stateProvider, timeRange, fNbRead);
         stateProvider.getTrace().sendRequest(request);
         fRequest = request;
     }
 
+    /**
+     * Create a new event request
+     *
+     * @param stateProvider
+     *            The state provider used to build the state system
+     * @param timeRange
+     *            The requested time range for the request
+     * @param nbRead
+     *            The event number at which to start the request
+     * @return A new event request
+     * @since 2.3
+     */
+    @VisibleForTesting
+    protected ITmfEventRequest createEventRequest(ITmfStateProvider stateProvider, TmfTimeRange timeRange, int nbRead) {
+        return new StateSystemEventRequest(stateProvider, timeRange, nbRead);
+    }
+
     private static boolean isCompleteTrace(ITmfTrace trace) {
         return !(trace instanceof ITmfTraceCompleteness) || ((ITmfTraceCompleteness) trace).isComplete();
     }
@@ -591,10 +659,10 @@ public abstract class TmfStateSystemAnalysisModule extends TmfAbstractAnalysisMo
      */
     @Override
     public @NonNull Map<@NonNull String, @NonNull String> getProperties() {
-        Map<@NonNull String, @NonNull String> properties = new HashMap<>();
+        Map<@NonNull String, @NonNull String> properties = super.getProperties();
 
         StateSystemBackendType backend = getBackendType();
-        properties.put(NonNullUtils.checkNotNull(Messages.TmfStateSystemAnalysisModule_PropertiesBackend), NonNullUtils.checkNotNull(backend.name()));
+        properties.put(NonNullUtils.checkNotNull(Messages.TmfStateSystemAnalysisModule_PropertiesBackend), backend.name());
         switch (backend) {
         case FULL:
         case PARTIAL:
This page took 0.029911 seconds and 5 git commands to generate.