You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by re...@apache.org on 2018/07/07 20:28:46 UTC

[uima-uimafit] branch feature/5808-destroy-auto-created-resource-managers-if-feasible-v2 created (now 0271ebf)

This is an automated email from the ASF dual-hosted git repository.

rec pushed a change to branch feature/5808-destroy-auto-created-resource-managers-if-feasible-v2
in repository https://gitbox.apache.org/repos/asf/uima-uimafit.git.


      at 0271ebf  [UIMA-5808] Destroy auto-created resource managers if feasible

This branch includes the following new commits:

     new 0271ebf  [UIMA-5808] Destroy auto-created resource managers if feasible

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[uima-uimafit] 01/01: [UIMA-5808] Destroy auto-created resource managers if feasible

Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rec pushed a commit to branch feature/5808-destroy-auto-created-resource-managers-if-feasible-v2
in repository https://gitbox.apache.org/repos/asf/uima-uimafit.git

commit 0271ebf7dc22705f1cf3999906933bb2945c9be2
Author: Richard Eckart de Castilho <re...@apache.org>
AuthorDate: Sat Jul 7 22:28:41 2018 +0200

    [UIMA-5808] Destroy auto-created resource managers if feasible
    
    - Destroy resource manager in JCasIterator
    - Use resource manager from reader in SimplePipeline to create CAS instead of creating a new one
    - Re-use resource manager from component in ConfigurationParameterInitializer if possible
---
 .../ConfigurationParameterInitializer.java         | 16 +++++++-
 .../uima/fit/factory/CollectionReaderFactory.java  |  7 ++--
 .../org/apache/uima/fit/pipeline/JCasIterable.java | 11 ++++-
 .../org/apache/uima/fit/pipeline/JCasIterator.java | 37 +++++++++++++++--
 .../apache/uima/fit/pipeline/SimplePipeline.java   | 47 +++++++++++++++++++---
 .../org/apache/uima/fit/util/LifeCycleUtil.java    | 13 ++++++
 6 files changed, 116 insertions(+), 15 deletions(-)

diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/component/initialize/ConfigurationParameterInitializer.java b/uimafit-core/src/main/java/org/apache/uima/fit/component/initialize/ConfigurationParameterInitializer.java
index 1b2f3ba..059b169 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/component/initialize/ConfigurationParameterInitializer.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/component/initialize/ConfigurationParameterInitializer.java
@@ -37,7 +37,9 @@ import org.apache.uima.resource.ConfigurationManager;
 import org.apache.uima.resource.CustomResourceSpecifier;
 import org.apache.uima.resource.DataResource;
 import org.apache.uima.resource.Parameter;
+import org.apache.uima.resource.Resource;
 import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.ResourceManager;
 import org.apache.uima.resource.ResourceSpecifier;
 import org.apache.uima.resource.metadata.ConfigurationParameterSettings;
 import org.apache.uima.resource.metadata.NameValuePair;
@@ -193,13 +195,23 @@ public final class ConfigurationParameterInitializer {
    */
   public static void initialize(final Object component, final Map<String, Object> map)
           throws ResourceInitializationException {
-    UimaContextAdmin context = UIMAFramework.newUimaContext(UIMAFramework.getLogger(),
-            ResourceManagerFactory.newResourceManager(), UIMAFramework.newConfigurationManager());
+    // If there is already a UimaContext then re-use that, otherwise create a new one.
+    UimaContextAdmin context;
+    if (component instanceof Resource) {
+      context = ((Resource) component).getUimaContextAdmin();
+    } else {
+      ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
+      context = UIMAFramework.newUimaContext(UIMAFramework.getLogger(), resMgr,
+              UIMAFramework.newConfigurationManager());
+    }
+
     ConfigurationManager cfgMgr = context.getConfigurationManager();
     cfgMgr.setSession(context.getSession());
+    
     for (Entry<String, Object> e : map.entrySet()) {
       cfgMgr.setConfigParameterValue(context.getQualifiedContextName() + e.getKey(), e.getValue());
     }
+
     initialize(component, context);
   }
 
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/factory/CollectionReaderFactory.java b/uimafit-core/src/main/java/org/apache/uima/fit/factory/CollectionReaderFactory.java
index 2ecb0c1..de53ef7 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/factory/CollectionReaderFactory.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/factory/CollectionReaderFactory.java
@@ -43,6 +43,7 @@ import org.apache.uima.fit.internal.ResourceManagerFactory;
 import org.apache.uima.resource.ExternalResourceDescription;
 import org.apache.uima.resource.ResourceCreationSpecifier;
 import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.ResourceManager;
 import org.apache.uima.resource.ResourceSpecifier;
 import org.apache.uima.resource.metadata.Capability;
 import org.apache.uima.resource.metadata.ConfigurationParameter;
@@ -162,12 +163,12 @@ public final class CollectionReaderFactory {
    */
   public static CollectionReader createReader(String descriptorName,
           Object... configurationData) throws UIMAException, IOException {
+    ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
     Import imp = UIMAFramework.getResourceSpecifierFactory().createImport();
     imp.setName(descriptorName);
-    URL url = imp.findAbsoluteUrl(ResourceManagerFactory.newResourceManager());
+    URL url = imp.findAbsoluteUrl(resMgr);
     ResourceSpecifier specifier = createResourceCreationSpecifier(url, configurationData);
-    return UIMAFramework.produceCollectionReader(specifier,
-            ResourceManagerFactory.newResourceManager(), null);
+    return UIMAFramework.produceCollectionReader(specifier, resMgr, null);
   }
 
   /**
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/pipeline/JCasIterable.java b/uimafit-core/src/main/java/org/apache/uima/fit/pipeline/JCasIterable.java
index f9af785..d65eb99 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/pipeline/JCasIterable.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/pipeline/JCasIterable.java
@@ -63,9 +63,11 @@ public class JCasIterable implements Iterable<JCas> {
     engines = aEngines;
   }
 
+  @Override
   public JCasIterator iterator() {
+    ResourceManager resMgr = null;
     try {
-      ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
+      resMgr = ResourceManagerFactory.newResourceManager();
       
       // Create the components
       CollectionReader readerInst = UIMAFramework.produceCollectionReader(reader, resMgr, null);
@@ -76,12 +78,17 @@ public class JCasIterable implements Iterable<JCas> {
       // Instantiate AAE
       AnalysisEngine aaeInst = UIMAFramework.produceAnalysisEngine(aaeDesc, resMgr, null);
       
-      JCasIterator i = new JCasIterator(readerInst, aaeInst);
+      JCasIterator i = new JCasIterator(resMgr, readerInst, aaeInst);
       i.setSelfComplete(true);
       i.setSelfDestroy(true);
       return i;
     } catch (UIMAException e) {
       throw new IllegalStateException(e);
     }
+    finally {
+      if (resMgr != null) {
+        resMgr.destroy();
+      }
+    }
   }
 }
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/pipeline/JCasIterator.java b/uimafit-core/src/main/java/org/apache/uima/fit/pipeline/JCasIterator.java
index b820847..79fb434 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/pipeline/JCasIterator.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/pipeline/JCasIterator.java
@@ -45,7 +45,6 @@ import org.apache.uima.util.CasCreationUtils;
  * A class implementing iteration over a the documents of a collection. Each element in the Iterable
  * is a JCas containing a single document. The documents have been loaded by the CollectionReader
  * and processed by the AnalysisEngine (if any).
- * 
  */
 public class JCasIterator implements Iterator<JCas> {
 
@@ -60,6 +59,10 @@ public class JCasIterator implements Iterator<JCas> {
   private boolean selfDestroy = false;
   
   private boolean destroyed = false;
+  
+  private ResourceManager resMgr;
+  
+  private boolean resourceManagerCreatedInternally = false;
 
   /**
    * Iterate over the documents loaded by the CollectionReader, running the AnalysisEngine on each
@@ -77,6 +80,29 @@ public class JCasIterator implements Iterator<JCas> {
    */
   public JCasIterator(final CollectionReader aReader, final AnalysisEngine... aEngines)
           throws CASException, ResourceInitializationException {
+    this(ResourceManagerFactory.newResourceManager(), aReader, aEngines);
+    resourceManagerCreatedInternally = true;
+  }
+
+  /**
+   * Iterate over the documents loaded by the CollectionReader, running the AnalysisEngine on each
+   * one before yielding them. By default, components get no lifecycle events, such as
+   * collectionProcessComplete or destroy when this constructor is used.
+   * @param aResMgr 
+   *          The ResourceManager. Should be the one also used by the CollectionReader and 
+   *          AnalysisEngines.
+   * @param aReader
+   *          The CollectionReader for loading documents.
+   * @param aEngines
+   *          The AnalysisEngines for processing documents.
+   * @throws ResourceInitializationException
+   *           if a failure occurs during initialization of the components
+   * @throws CASException
+   *           if the JCas could not be initialized
+   */
+  public JCasIterator(final ResourceManager aResMgr, final CollectionReader aReader,
+          final AnalysisEngine... aEngines) throws CASException, ResourceInitializationException {
+    resMgr = aResMgr;
     collectionReader = aReader;
     analysisEngines = aEngines;
 
@@ -86,8 +112,7 @@ public class JCasIterator implements Iterator<JCas> {
       metaData.add(ae.getProcessingResourceMetaData());
     }
 
-    ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
-    jCas = CasCreationUtils.createCas(metaData, null, resMgr).getJCas();
+    jCas = CasCreationUtils.createCas(metaData, null, aResMgr).getJCas();
     collectionReader.typeSystemInit(jCas.getTypeSystem());
   }
 
@@ -111,6 +136,7 @@ public class JCasIterator implements Iterator<JCas> {
     this(aReader, createEngine(NoOpAnnotator.class, aTypeSystemDescription));
   }
 
+  @Override
   public boolean hasNext() {
     if (destroyed) {
       return false;
@@ -132,6 +158,7 @@ public class JCasIterator implements Iterator<JCas> {
     }
   }
 
+  @Override
   public JCas next() {
     jCas.reset();
     boolean error = true;
@@ -170,6 +197,7 @@ public class JCasIterator implements Iterator<JCas> {
     return jCas;
   }
 
+  @Override
   public void remove() {
     throw new UnsupportedOperationException();
   }
@@ -192,6 +220,9 @@ public class JCasIterator implements Iterator<JCas> {
       LifeCycleUtil.close(collectionReader);
       LifeCycleUtil.destroy(collectionReader);
       LifeCycleUtil.destroy(analysisEngines);
+      if (resourceManagerCreatedInternally) {
+        LifeCycleUtil.destroy(resMgr);
+      }
       destroyed = true;
     }
   }
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/pipeline/SimplePipeline.java b/uimafit-core/src/main/java/org/apache/uima/fit/pipeline/SimplePipeline.java
index 72365cc..25ab4ff 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/pipeline/SimplePipeline.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/pipeline/SimplePipeline.java
@@ -67,6 +67,9 @@ public final class SimplePipeline {
    * Note that with this method, external resources cannot be shared between the reader and the
    * analysis engines. They can be shared amongst the analysis engines.
    * </p>
+   * <p>
+   * The CAS is created using the resource manager used by the collection reader.
+   * </p>
    * 
    * @param reader
    *          The CollectionReader that loads the documents into the CAS.
@@ -90,9 +93,8 @@ public final class SimplePipeline {
       aae = createEngine(aaeDesc);
   
       // Create CAS from merged metadata
-      ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
       final CAS cas = CasCreationUtils.createCas(asList(reader.getMetaData(), aae.getMetaData()), 
-              null, resMgr);
+              null, reader.getResourceManager());
       reader.typeSystemInit(cas.getTypeSystem());
 
       // Process
@@ -153,8 +155,9 @@ public final class SimplePipeline {
     
     CollectionReader reader = null;
     AnalysisEngine aae = null;
+    ResourceManager resMgr = null;
     try {
-      ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
+      resMgr = ResourceManagerFactory.newResourceManager();
       
       // Create the components
       reader = UIMAFramework.produceCollectionReader(readerDesc, resMgr, null);
@@ -183,6 +186,7 @@ public final class SimplePipeline {
       // Destroy
       LifeCycleUtil.destroy(reader);
       LifeCycleUtil.destroy(aae);
+      LifeCycleUtil.destroy(resMgr);
     }
   }
 
@@ -199,6 +203,9 @@ public final class SimplePipeline {
    * External resources can only be shared between the reader and/or the analysis engines if the
    * reader/engines have been previously instantiated using a shared resource manager.
    * </p>
+   * <p>
+   * The CAS is created using the resource manager used by the collection reader.
+   * </p>
    * 
    * @param reader
    *          a collection reader
@@ -211,14 +218,44 @@ public final class SimplePipeline {
    */
   public static void runPipeline(final CollectionReader reader, final AnalysisEngine... engines)
           throws UIMAException, IOException {
+    runPipeline(reader.getResourceManager(), reader, engines);
+  }
+  
+  /**
+   * <p>
+   * Provides a simple way to run a pipeline for a given collection reader and sequence of analysis
+   * engines. After processing all CASes provided by the reader, the method calls
+   * {@link AnalysisEngine#collectionProcessComplete() collectionProcessComplete()} on the engines.
+   * Note that {@link AnalysisEngine#destroy()} and {@link CollectionReader#destroy()} are
+   * <b>NOT</b> called. As the components were instantiated by the caller, they must also be managed
+   * (i.e. destroyed) the caller.
+   * </p>
+   * <p>
+   * External resources can only be shared between the reader and/or the analysis engines if the
+   * reader/engines have been previously instantiated using a shared resource manager.
+   * </p>
+   * 
+   * @param aResMgr
+   *          a resource manager. Normally the same one used by the collection reader and analysis
+   *          engines.
+   * @param reader
+   *          a collection reader
+   * @param engines
+   *          a sequence of analysis engines
+   * @throws UIMAException
+   *           if there is a problem initializing or running the CPE.
+   * @throws IOException
+   *           if there is an I/O problem in the reader
+   */
+  public static void runPipeline(final ResourceManager aResMgr, final CollectionReader reader,
+          final AnalysisEngine... engines) throws UIMAException, IOException {
     final List<ResourceMetaData> metaData = new ArrayList<ResourceMetaData>();
     metaData.add(reader.getMetaData());
     for (AnalysisEngine engine : engines) {
       metaData.add(engine.getMetaData());
     }
 
-    ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
-    final CAS cas = CasCreationUtils.createCas(metaData, null, resMgr);
+    final CAS cas = CasCreationUtils.createCas(metaData, null, aResMgr);
     reader.typeSystemInit(cas.getTypeSystem());
 
     while (reader.hasNext()) {
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/util/LifeCycleUtil.java b/uimafit-core/src/main/java/org/apache/uima/fit/util/LifeCycleUtil.java
index 799785e..5a10dc7 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/util/LifeCycleUtil.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/util/LifeCycleUtil.java
@@ -24,6 +24,7 @@ import org.apache.uima.analysis_engine.AnalysisEngine;
 import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
 import org.apache.uima.collection.base_cpm.BaseCollectionReader;
 import org.apache.uima.resource.Resource;
+import org.apache.uima.resource.ResourceManager;
 
 /**
  * Helper methods to handle the life cycle of UIMA components.
@@ -51,6 +52,18 @@ public final class LifeCycleUtil {
   }
 
   /**
+   * Destroy a set of {@link ResourceManager resource manager}.
+   * 
+   * @param aResMgr
+   *          the resource manager to destroy
+   */
+  public static void destroy(final ResourceManager aResMgr) {
+    if (aResMgr != null) {
+      aResMgr.destroy();
+    }
+  }
+
+  /**
    * Destroy a set of {@link Resource resources}.
    * 
    * @param resources