You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by cp...@apache.org on 2017/06/27 14:08:16 UTC

[1/2] lucene-solr:master: Fix three ex[c]eption typos.

Repository: lucene-solr
Updated Branches:
  refs/heads/master e6f48ca6b -> 808171ac0


Fix three ex[c]eption typos.


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/808171ac
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/808171ac
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/808171ac

Branch: refs/heads/master
Commit: 808171ac0001e952109c4a492b0a0121c60cea75
Parents: 701c73d
Author: Christine Poerschke <cp...@apache.org>
Authored: Tue Jun 27 14:46:39 2017 +0100
Committer: Christine Poerschke <cp...@apache.org>
Committed: Tue Jun 27 15:07:40 2017 +0100

----------------------------------------------------------------------
 lucene/core/src/java/org/apache/lucene/analysis/Analyzer.java | 4 ++--
 solr/core/src/java/org/apache/solr/core/CoreContainer.java    | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/808171ac/lucene/core/src/java/org/apache/lucene/analysis/Analyzer.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/analysis/Analyzer.java b/lucene/core/src/java/org/apache/lucene/analysis/Analyzer.java
index 3a5d41c..6bdc943 100644
--- a/lucene/core/src/java/org/apache/lucene/analysis/Analyzer.java
+++ b/lucene/core/src/java/org/apache/lucene/analysis/Analyzer.java
@@ -235,7 +235,7 @@ public abstract class Analyzer implements Closeable {
         }
         filteredText = builder.toString();
       } catch (IOException e) {
-        throw new IllegalStateException("Normalization threw an unexpected exeption", e);
+        throw new IllegalStateException("Normalization threw an unexpected exception", e);
       }
 
       final AttributeFactory attributeFactory = attributeFactory(fieldName);
@@ -258,7 +258,7 @@ public abstract class Analyzer implements Closeable {
         return term;
       }
     } catch (IOException e) {
-      throw new IllegalStateException("Normalization threw an unexpected exeption", e);
+      throw new IllegalStateException("Normalization threw an unexpected exception", e);
     }
   }
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/808171ac/solr/core/src/java/org/apache/solr/core/CoreContainer.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/core/CoreContainer.java b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
index 6055acf..90bbf5d 100644
--- a/solr/core/src/java/org/apache/solr/core/CoreContainer.java
+++ b/solr/core/src/java/org/apache/solr/core/CoreContainer.java
@@ -1032,7 +1032,7 @@ public class CoreContainer {
       }
     }
     
-    // If no CorruptIndexExeption, nothing we can try here
+    // If no CorruptIndexException, nothing we can try here
     if (cause == null) throw original;
     
     CoreInitFailedAction action = CoreInitFailedAction.valueOf(System.getProperty(CoreInitFailedAction.class.getSimpleName(), "none"));


[2/2] lucene-solr git commit: SOLR-10506: Fix memory leak (upon collection reload or ZooKeeper session expiry) in ZkIndexSchemaReader. (Torsten Bøgh Köster, Christine Poerschke, Jörg Rathlev, Mike Drob)

Posted by cp...@apache.org.
SOLR-10506: Fix memory leak (upon collection reload or ZooKeeper session expiry) in ZkIndexSchemaReader.
(Torsten Bøgh Köster, Christine Poerschke, Jörg Rathlev, Mike Drob)


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/701c73d4
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/701c73d4
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/701c73d4

Branch: refs/heads/master
Commit: 701c73d45a0188d006316e9a3168ad6b70e0fac9
Parents: e6f48ca
Author: Christine Poerschke <cp...@apache.org>
Authored: Tue Jun 27 14:04:58 2017 +0100
Committer: Christine Poerschke <cp...@apache.org>
Committed: Tue Jun 27 15:07:40 2017 +0100

----------------------------------------------------------------------
 solr/CHANGES.txt                                |   3 +
 .../apache/solr/schema/ZkIndexSchemaReader.java | 105 ++++++++++++-------
 .../apache/solr/schema/SchemaWatcherTest.java   |  56 ++++++++++
 3 files changed, 128 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/701c73d4/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 7002993..3f25c26 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -211,6 +211,9 @@ Bug Fixes
 
 * SOLR-10948: Fix extraction component to treat DatePointField the same as TrieDateField (hossman)
 
+* SOLR-10506: Fix memory leak (upon collection reload or ZooKeeper session expiry) in ZkIndexSchemaReader.
+  (Torsten Bøgh Köster, Christine Poerschke, Jörg Rathlev, Mike Drob)
+
 Optimizations
 ----------------------
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/701c73d4/solr/core/src/java/org/apache/solr/schema/ZkIndexSchemaReader.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/schema/ZkIndexSchemaReader.java b/solr/core/src/java/org/apache/solr/schema/ZkIndexSchemaReader.java
index e719404..d83762a 100644
--- a/solr/core/src/java/org/apache/solr/schema/ZkIndexSchemaReader.java
+++ b/solr/core/src/java/org/apache/solr/schema/ZkIndexSchemaReader.java
@@ -42,7 +42,7 @@ public class ZkIndexSchemaReader implements OnReconnect {
   private SolrZkClient zkClient;
   private String managedSchemaPath;
   private final String uniqueCoreId; // used in equals impl to uniquely identify the core that we're dependent on
-  private boolean isRemoved = false;
+  private SchemaWatcher schemaWatcher;
 
   public ZkIndexSchemaReader(ManagedIndexSchemaFactory managedIndexSchemaFactory, SolrCore solrCore) {
     this.managedIndexSchemaFactory = managedIndexSchemaFactory;
@@ -58,16 +58,20 @@ public class ZkIndexSchemaReader implements OnReconnect {
         CoreContainer cc = core.getCoreContainer();
         if (cc.isZooKeeperAware()) {
           log.debug("Removing ZkIndexSchemaReader OnReconnect listener as core "+core.getName()+" is shutting down.");
-          ZkIndexSchemaReader.this.isRemoved = true;
           cc.getZkController().removeOnReconnectListener(ZkIndexSchemaReader.this);
         }
       }
 
       @Override
-      public void postClose(SolrCore core) {}
+      public void postClose(SolrCore core) {
+        // The watcher is still registered with Zookeeper, and holds a
+        // reference to the schema reader, which indirectly references the
+        // SolrCore and would prevent it from being garbage collected.
+        schemaWatcher.discardReaderReference();
+      }
     });
 
-    createSchemaWatcher();
+    this.schemaWatcher = createSchemaWatcher();
 
     zkLoader.getZkController().addOnReconnectListener(this);
   }
@@ -76,39 +80,17 @@ public class ZkIndexSchemaReader implements OnReconnect {
     return managedIndexSchemaFactory.getSchemaUpdateLock(); 
   }
 
-  public void createSchemaWatcher() {
+  /**
+   * Creates a schema watcher and returns it for controlling purposes.
+   * 
+   * @return the registered {@linkplain SchemaWatcher}.
+   */
+  public SchemaWatcher createSchemaWatcher() {
     log.info("Creating ZooKeeper watch for the managed schema at " + managedSchemaPath);
 
+    SchemaWatcher watcher = new SchemaWatcher(this);
     try {
-      zkClient.exists(managedSchemaPath, new Watcher() {
-        @Override
-        public void process(WatchedEvent event) {
-
-          if (ZkIndexSchemaReader.this.isRemoved) {
-            return; // the core for this reader has already been removed, don't process this event
-          }
-
-          // session events are not change events, and do not remove the watcher
-          if (Event.EventType.None.equals(event.getType())) {
-            return;
-          }
-          log.info("A schema change: {}, has occurred - updating schema from ZooKeeper ...", event);
-          try {
-            updateSchema(this, -1);
-          } catch (KeeperException e) {
-            if (e.code() == KeeperException.Code.SESSIONEXPIRED || e.code() == KeeperException.Code.CONNECTIONLOSS) {
-              log.warn("ZooKeeper watch triggered, but Solr cannot talk to ZK");
-              return;
-            }
-            log.error("", e);
-            throw new ZooKeeperException(ErrorCode.SERVER_ERROR, "", e);
-          } catch (InterruptedException e) {
-            // Restore the interrupted status
-            Thread.currentThread().interrupt();
-            log.warn("", e);
-          }
-        }
-      }, true);
+      zkClient.exists(managedSchemaPath, watcher, true);
     } catch (KeeperException e) {
       final String msg = "Error creating ZooKeeper watch for the managed schema";
       log.error(msg, e);
@@ -118,6 +100,56 @@ public class ZkIndexSchemaReader implements OnReconnect {
       Thread.currentThread().interrupt();
       log.warn("", e);
     }
+    
+    return watcher;
+  }
+  
+  /**
+   * Watches for schema changes and triggers updates in the {@linkplain ZkIndexSchemaReader}.
+   */
+  public static class SchemaWatcher implements Watcher {
+
+    private ZkIndexSchemaReader schemaReader;
+
+    public SchemaWatcher(ZkIndexSchemaReader reader) {
+      this.schemaReader = reader;
+    }
+
+    @Override
+    public void process(WatchedEvent event) {
+      ZkIndexSchemaReader indexSchemaReader = schemaReader;
+
+      if (indexSchemaReader == null) {
+        return; // the core for this reader has already been removed, don't process this event
+      }
+
+      // session events are not change events, and do not remove the watcher
+      if (Event.EventType.None.equals(event.getType())) {
+        return;
+      }
+      log.info("A schema change: {}, has occurred - updating schema from ZooKeeper ...", event);
+      try {
+        indexSchemaReader.updateSchema(this, -1);
+      } catch (KeeperException e) {
+        if (e.code() == KeeperException.Code.SESSIONEXPIRED || e.code() == KeeperException.Code.CONNECTIONLOSS) {
+          log.warn("ZooKeeper watch triggered, but Solr cannot talk to ZK");
+          return;
+        }
+        log.error("", e);
+        throw new ZooKeeperException(ErrorCode.SERVER_ERROR, "", e);
+      } catch (InterruptedException e) {
+        // Restore the interrupted status
+        Thread.currentThread().interrupt();
+        log.warn("", e);
+      }
+    }
+
+    /**
+     * Discard the reference to the {@code ZkIndexSchemaReader}.
+     */
+    public void discardReaderReference() {
+      schemaReader = null;
+    }
   }
 
   public ManagedIndexSchema refreshSchemaFromZk(int expectedZkVersion) throws KeeperException, InterruptedException {
@@ -125,7 +157,8 @@ public class ZkIndexSchemaReader implements OnReconnect {
     return managedIndexSchemaFactory.getSchema();
   }
 
-  private void updateSchema(Watcher watcher, int expectedZkVersion) throws KeeperException, InterruptedException {
+  // package visibility for test purposes
+  void updateSchema(Watcher watcher, int expectedZkVersion) throws KeeperException, InterruptedException {
     Stat stat = new Stat();
     synchronized (getSchemaUpdateLock()) {
       final ManagedIndexSchema oldSchema = managedIndexSchemaFactory.getSchema();
@@ -157,7 +190,7 @@ public class ZkIndexSchemaReader implements OnReconnect {
   public void command() {
     try {
       // setup a new watcher to get notified when the managed schema changes
-      createSchemaWatcher();
+      schemaWatcher = createSchemaWatcher();
       // force update now as the schema may have changed while our zk session was expired
       updateSchema(null, -1);
     } catch (Exception exc) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/701c73d4/solr/core/src/test/org/apache/solr/schema/SchemaWatcherTest.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/schema/SchemaWatcherTest.java b/solr/core/src/test/org/apache/solr/schema/SchemaWatcherTest.java
new file mode 100644
index 0000000..4d46aad
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/schema/SchemaWatcherTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.schema;
+
+import org.apache.solr.schema.ZkIndexSchemaReader.SchemaWatcher;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher.Event.EventType;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+public class SchemaWatcherTest {
+
+  private ZkIndexSchemaReader mockSchemaReader;
+  private SchemaWatcher schemaWatcher;
+
+  @Before
+  public void setUp() throws Exception {
+    mockSchemaReader = mock(ZkIndexSchemaReader.class);
+    schemaWatcher = new SchemaWatcher(mockSchemaReader);
+  }
+
+  @Test
+  public void testProcess() throws Exception {
+    schemaWatcher.process(new WatchedEvent(EventType.NodeDataChanged, KeeperState.SyncConnected, "/test"));
+    verify(mockSchemaReader).updateSchema(schemaWatcher, -1);
+  }
+
+  @Test
+  public void testDiscardReaderReference() throws Exception {
+    schemaWatcher.discardReaderReference();
+
+    schemaWatcher.process(new WatchedEvent(EventType.NodeDataChanged, KeeperState.SyncConnected, "/test"));
+    // after discardReaderReference, SchemaWatcher should no longer hold a ref to the reader
+    verifyZeroInteractions(mockSchemaReader);
+  }
+}