You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by us...@apache.org on 2019/04/13 08:41:30 UTC

[lucene-solr] branch jira/LUCENE-8738 updated: LUCENE-8738: Port TransientSolrCoreCache observer pattern to Java 11

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

uschindler pushed a commit to branch jira/LUCENE-8738
in repository https://gitbox.apache.org/repos/asf/lucene-solr.git


The following commit(s) were added to refs/heads/jira/LUCENE-8738 by this push:
     new 13f8d1e  LUCENE-8738: Port TransientSolrCoreCache observer pattern to Java 11
13f8d1e is described below

commit 13f8d1ead9fbc6ecb2206813284b8c08d1f37995
Author: Uwe Schindler <us...@apache.org>
AuthorDate: Sat Apr 13 10:41:00 2019 +0200

    LUCENE-8738: Port TransientSolrCoreCache observer pattern to Java 11
---
 solr/CHANGES.txt                                   |  6 ++++
 .../apache/solr/core/SolrCoreCloseListener.java    | 42 ++++++++++++++++++++++
 .../src/java/org/apache/solr/core/SolrCores.java   |  9 ++---
 .../apache/solr/core/TransientSolrCoreCache.java   | 27 +++++++++++++-
 .../solr/core/TransientSolrCoreCacheDefault.java   | 14 +++-----
 5 files changed, 82 insertions(+), 16 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 51839ba..d702da1 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -48,6 +48,12 @@ Upgrade Notes
 * SOLR-13323: The unused package org.apache.solr.internal.csv.writer and associated classes/tests that were easily
   confused with but not used by org.apache.solr.response.CSVWriter (or any other code) have been removed (Gus Heck)
 
+* LUCENE-8738: Du to the change to Java 11 as a minimum version, TransientSolrCoreCache no longer extends
+  the java.util.Observable, which was deprecated in Java 9. The implementation was therefore replaced by a more
+  type-safe implementation. If a plugin implemented its own TransientSolrCoreCache, the implementation needs
+  to be changed to call the new methods for registering/deregistering listener and notify them.
+  (Uwe Schindler, Erick Erickson, Adrien Grand)
+
 New Features
 ----------------------
 * SOLR-13131: Category Routed Aliases are now available for data driven assignment of documents to collections based on
diff --git a/solr/core/src/java/org/apache/solr/core/SolrCoreCloseListener.java b/solr/core/src/java/org/apache/solr/core/SolrCoreCloseListener.java
new file mode 100644
index 0000000..4a5b41c
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/core/SolrCoreCloseListener.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.core;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+/**
+ * Notifies observers implementing this class about cores that need to be closed.
+ */
+public interface SolrCoreCloseListener extends PropertyChangeListener {
+
+  /**
+   * Called by TransientSolrCoreCache to notify the CoreContainer / SolrCores about cores that need to be closed.
+   * @param core Core that need to be queued for close
+   */
+  void queueCoreClose(SolrCore core);
+
+  @Override
+  default void propertyChange(PropertyChangeEvent evt) {
+    queueCoreClose((SolrCore) evt.getOldValue());
+  }
+
+}
+
+
+  
diff --git a/solr/core/src/java/org/apache/solr/core/SolrCores.java b/solr/core/src/java/org/apache/solr/core/SolrCores.java
index 73d97da..43034a5 100644
--- a/solr/core/src/java/org/apache/solr/core/SolrCores.java
+++ b/solr/core/src/java/org/apache/solr/core/SolrCores.java
@@ -25,8 +25,6 @@ import org.apache.solr.util.DefaultSolrThreadFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
 import java.lang.invoke.MethodHandles;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -42,7 +40,7 @@ import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeUnit;
 
 
-class SolrCores implements PropertyChangeListener {
+class SolrCores implements SolrCoreCloseListener {
 
   private static Object modifyLock = new Object(); // for locking around manipulating any of the core maps.
   private final Map<String, SolrCore> cores = new LinkedHashMap<>(); // For "permanent" cores
@@ -536,10 +534,9 @@ class SolrCores implements PropertyChangeListener {
 
   // Let transient cache implementation tell us when it ages out a core
   @Override
-  public void propertyChange(PropertyChangeEvent evt) {
+  public void queueCoreClose(SolrCore core) {
     synchronized (modifyLock) {
       // Erick Erickson debugging TestLazyCores. With this un-commented, we get no testLazyCores failures.
-//      SolrCore core = (SolrCore) arg;
 //      SolrQueryRequest req = new LocalSolrQueryRequest(core, new ModifiableSolrParams());
 //      CommitUpdateCommand cmd = new CommitUpdateCommand(req, false);
 //      cmd.openSearcher = false;
@@ -549,7 +546,7 @@ class SolrCores implements PropertyChangeListener {
 //      } catch (IOException e) {
 //        log.warn("Caught exception trying to close a transient core, ignoring as it should be benign");
 //      }
-      pendingCloses.add((SolrCore) evt.getOldValue()); // Essentially just queue this core up for closing.
+      pendingCloses.add(core); // Essentially just queue this core up for closing.
       modifyLock.notifyAll(); // Wakes up closer thread too
     }
   }
diff --git a/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCache.java b/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCache.java
index 3f6cc8c..3af7e23 100644
--- a/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCache.java
+++ b/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCache.java
@@ -18,6 +18,7 @@
 package org.apache.solr.core;
 
 
+import java.beans.PropertyChangeSupport;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -44,7 +45,7 @@ import org.apache.http.annotation.Experimental;
  *          necessary and to coordinate shutting down cores, manipulating the internal structures and the like..
  *          
  *          The only real action you should _initiate_ is to close a core for whatever reason, and do that by 
- *          calling notifyObservers(coreToClose); The observer will call back to removeCore(name) at the appropriate 
+ *          calling notifyCoreCloseListener(coreToClose); The observer will call back to removeCore(name) at the appropriate 
  *          time. There is no need to directly remove the core _at that time_ from the transientCores list, a call
  *          will come back to this class when CoreContainer is closing this core.
  *          
@@ -120,6 +121,30 @@ public abstract class TransientSolrCoreCache {
   // These two methods allow custom implementations to communicate arbitrary information as necessary.
   public abstract int getStatus(String coreName);
   public abstract void setStatus(String coreName, int status);
+  
+  
+  /**
+   * Registers a listener to be notified when a core should close
+   */
+  protected final void registerCoreCloseListener(SolrCoreCloseListener listener) {
+    pcs.addPropertyChangeListener(listener);
+  }
+  
+  /**
+   * Removes a listener registered by {@link #registerCoreCloseListener(SolrCoreCloseListener)}
+   */
+  protected final void removeCoreCloseListener(SolrCoreCloseListener listener) {
+    pcs.removePropertyChangeListener(listener);
+  }
+  
+  /**
+   * Notifies all listeners to close a core that were previously registered using {@link #registerCoreCloseListener(SolrCoreCloseListener)}
+   */
+  protected final void notifyCoreCloseListeners(SolrCore core) {
+    pcs.firePropertyChange("core", core, null);
+  }
+  
+  private final PropertyChangeSupport pcs = new  PropertyChangeSupport(this);
 }
 
 
diff --git a/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCacheDefault.java b/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCacheDefault.java
index 5cd3537..0b3db4b 100644
--- a/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCacheDefault.java
+++ b/solr/core/src/java/org/apache/solr/core/TransientSolrCoreCacheDefault.java
@@ -17,8 +17,6 @@
 
 package org.apache.solr.core;
 
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
 import java.lang.invoke.MethodHandles;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -37,7 +35,7 @@ public class TransientSolrCoreCacheDefault extends TransientSolrCoreCache {
 
   private int cacheSize = NodeConfig.NodeConfigBuilder.DEFAULT_TRANSIENT_CACHE_SIZE;
 
-  protected PropertyChangeListener coreChangeListener;
+  protected SolrCoreCloseListener coreCloseListener;
   protected CoreContainer coreContainer;
 
   protected final Map<String, CoreDescriptor> transientDescriptors = new LinkedHashMap<>();
@@ -45,14 +43,12 @@ public class TransientSolrCoreCacheDefault extends TransientSolrCoreCache {
   //WARNING! The _only_ place you put anything into the list of transient cores is with the putTransientCore method!
   protected Map<String, SolrCore> transientCores = new LinkedHashMap<>(); // For "lazily loaded" cores
 
-  private final PropertyChangeSupport pcs = new  PropertyChangeSupport(this);
-
   /**
    * @param container The enclosing CoreContainer. It allows us to access everything we need.
    */
   public TransientSolrCoreCacheDefault(final CoreContainer container) {
     this.coreContainer = container;
-    this.coreChangeListener= coreContainer.solrCores;
+    this.coreCloseListener = coreContainer.solrCores;
     
     NodeConfig cfg = container.getNodeConfig();
     if (cfg.getTransientCachePluginInfo() == null) {
@@ -83,7 +79,7 @@ public class TransientSolrCoreCacheDefault extends TransientSolrCoreCache {
     }
 
     log.info("Allocating transient cache for {} transient cores", cacheSize);
-    pcs.addPropertyChangeListener(this.coreChangeListener);
+    this.registerCoreCloseListener(this.coreCloseListener);
     // it's possible for cache
     if (cacheSize < 0) { // Trap old flag
       cacheSize = Integer.MAX_VALUE;
@@ -95,8 +91,8 @@ public class TransientSolrCoreCacheDefault extends TransientSolrCoreCache {
       protected boolean removeEldestEntry(Map.Entry<String, SolrCore> eldest) {
         if (size() > cacheSize) {
           SolrCore coreToClose = eldest.getValue();
-          pcs.firePropertyChange("core", coreToClose, null);
           log.info("Closing transient core [{}]", coreToClose.getName());
+          notifyCoreCloseListeners(coreToClose);
           return true;
         }
         return false;
@@ -186,7 +182,7 @@ public class TransientSolrCoreCacheDefault extends TransientSolrCoreCache {
    */
   @Override
   public void close() {
-    pcs.removePropertyChangeListener(this.coreChangeListener);
+    this.removeCoreCloseListener(this.coreCloseListener);
   }