lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a.@apache.org
Subject lucene-solr:jira/solr-11320: SOLR-11320: Add SolrCloseableLatch that can be interrupted when a SolrCloseable is closed.
Date Mon, 23 Oct 2017 10:50:48 GMT
Repository: lucene-solr
Updated Branches:
  refs/heads/jira/solr-11320 4142b15e3 -> f87a1471c


SOLR-11320: Add SolrCloseableLatch that can be interrupted when a SolrCloseable is
closed.


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

Branch: refs/heads/jira/solr-11320
Commit: f87a1471c856749d67066eb85e334aff0e920186
Parents: 4142b15
Author: Andrzej Bialecki <ab@apache.org>
Authored: Mon Oct 23 12:50:10 2017 +0200
Committer: Andrzej Bialecki <ab@apache.org>
Committed: Mon Oct 23 12:50:10 2017 +0200

----------------------------------------------------------------------
 .../apache/solr/cloud/ActiveReplicaWatcher.java | 26 ++++----
 .../org/apache/solr/cloud/AddReplicaCmd.java    |  8 +--
 .../org/apache/solr/cloud/CreateShardCmd.java   |  6 +-
 .../solr/cloud/LeaderRecoveryWatcher.java       | 16 ++---
 .../org/apache/solr/cloud/MoveReplicaCmd.java   |  4 +-
 .../java/org/apache/solr/cloud/Overseer.java    |  8 ++-
 .../cloud/OverseerCollectionMessageHandler.java | 12 +++-
 .../org/apache/solr/cloud/ReplaceNodeCmd.java   |  8 +--
 .../autoscaling/OverseerTriggerThread.java      |  8 ++-
 .../cloud/autoscaling/SolrCloudManager.java     |  8 +--
 .../org/apache/solr/common/SolrCloseable.java   | 30 +++++++++
 .../apache/solr/common/SolrCloseableLatch.java  | 65 ++++++++++++++++++++
 12 files changed, 156 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f87a1471/solr/core/src/java/org/apache/solr/cloud/ActiveReplicaWatcher.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/ActiveReplicaWatcher.java b/solr/core/src/java/org/apache/solr/cloud/ActiveReplicaWatcher.java
index 3819aec..dcb9dfd 100644
--- a/solr/core/src/java/org/apache/solr/cloud/ActiveReplicaWatcher.java
+++ b/solr/core/src/java/org/apache/solr/cloud/ActiveReplicaWatcher.java
@@ -20,8 +20,8 @@ import java.lang.invoke.MethodHandles;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
-import java.util.concurrent.CountDownLatch;
 
+import org.apache.solr.common.SolrCloseableLatch;
 import org.apache.solr.common.cloud.CollectionStateWatcher;
 import org.apache.solr.common.cloud.DocCollection;
 import org.apache.solr.common.cloud.Replica;
@@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory;
  * Watch for replicas to become {@link org.apache.solr.common.cloud.Replica.State#ACTIVE}.
Watcher is
  * terminated (its {@link #onStateChanged(Set, DocCollection)} method returns false) when
all listed
  * replicas become active.
- * <p>Additionally, the provided {@link CountDownLatch} instance can be used to await
+ * <p>Additionally, the provided {@link SolrCloseableLatch} instance can be used to
await
  * for all listed replicas to become active.</p>
  */
 public class ActiveReplicaWatcher implements CollectionStateWatcher {
@@ -44,17 +44,17 @@ public class ActiveReplicaWatcher implements CollectionStateWatcher {
   private final List<String> solrCoreNames = new ArrayList<>();
   private final List<Replica> activeReplicas = new ArrayList<>();
 
-  private CountDownLatch countDownLatch;
+  private SolrCloseableLatch latch;
 
   /**
    * Construct the watcher. At least one replicaId or solrCoreName must be provided.
    * @param collection collection name
    * @param replicaIds list of replica id-s
    * @param solrCoreNames list of SolrCore names
-   * @param countDownLatch optional latch to await for all provided replicas to become active.
This latch will be
+   * @param latch optional latch to await for all provided replicas to become active. This
latch will be
    *                       counted down by at most the number of provided replica id-s /
SolrCore names.
    */
-  public ActiveReplicaWatcher(String collection, List<String> replicaIds, List<String>
solrCoreNames, CountDownLatch countDownLatch) {
+  public ActiveReplicaWatcher(String collection, List<String> replicaIds, List<String>
solrCoreNames, SolrCloseableLatch latch) {
     if (replicaIds == null && solrCoreNames == null) {
       throw new IllegalArgumentException("Either replicaId or solrCoreName must be provided.");
     }
@@ -68,7 +68,7 @@ public class ActiveReplicaWatcher implements CollectionStateWatcher {
       throw new IllegalArgumentException("At least one replicaId or solrCoreName must be
provided");
     }
     this.collection = collection;
-    this.countDownLatch = countDownLatch;
+    this.latch = latch;
   }
 
   /**
@@ -111,11 +111,11 @@ public class ActiveReplicaWatcher implements CollectionStateWatcher
{
 
   @Override
   public boolean onStateChanged(Set<String> liveNodes, DocCollection collectionState)
{
-    log.debug("-- onStateChanged: " + collectionState);
+    log.info("-- onStateChanged: " + collectionState);
     if (collectionState == null) { // collection has been deleted - don't wait
-      if (countDownLatch != null) {
+      if (latch != null) {
         for (int i = 0; i < replicaIds.size() + solrCoreNames.size(); i++) {
-          countDownLatch.countDown();
+          latch.countDown();
         }
       }
       replicaIds.clear();
@@ -128,16 +128,16 @@ public class ActiveReplicaWatcher implements CollectionStateWatcher
{
           if (replica.isActive(liveNodes)) {
             activeReplicas.add(replica);
             replicaIds.remove(replica.getName());
-            if (countDownLatch != null) {
-              countDownLatch.countDown();
+            if (latch != null) {
+              latch.countDown();
             }
           }
         } else if (solrCoreNames.contains(replica.getStr(ZkStateReader.CORE_NAME_PROP)))
{
           if (replica.isActive(liveNodes)) {
             activeReplicas.add(replica);
             solrCoreNames.remove(replica.getStr(ZkStateReader.CORE_NAME_PROP));
-            if (countDownLatch != null) {
-              countDownLatch.countDown();
+            if (latch != null) {
+              latch.countDown();
             }
           }
         }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f87a1471/solr/core/src/java/org/apache/solr/cloud/AddReplicaCmd.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/AddReplicaCmd.java b/solr/core/src/java/org/apache/solr/cloud/AddReplicaCmd.java
index f533c56..2efc036 100644
--- a/solr/core/src/java/org/apache/solr/cloud/AddReplicaCmd.java
+++ b/solr/core/src/java/org/apache/solr/cloud/AddReplicaCmd.java
@@ -25,13 +25,13 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.solr.client.solrj.cloud.autoscaling.Policy;
 import org.apache.solr.client.solrj.cloud.autoscaling.PolicyHelper;
+import org.apache.solr.common.SolrCloseableLatch;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.cloud.ClusterState;
 import org.apache.solr.common.cloud.DocCollection;
@@ -229,12 +229,12 @@ public class AddReplicaCmd implements OverseerCollectionMessageHandler.Cmd
{
 
     if (!parallel || waitForFinalState) {
       if (waitForFinalState) {
-        CountDownLatch countDownLatch = new CountDownLatch(1);
-        ActiveReplicaWatcher watcher = new ActiveReplicaWatcher(collection, null, Collections.singletonList(coreName),
countDownLatch);
+        SolrCloseableLatch latch = new SolrCloseableLatch(1, ocmh);
+        ActiveReplicaWatcher watcher = new ActiveReplicaWatcher(collection, null, Collections.singletonList(coreName),
latch);
         try {
           zkStateReader.registerCollectionStateWatcher(collection, watcher);
           runnable.run();
-          if (!countDownLatch.await(timeout, TimeUnit.SECONDS)) {
+          if (!latch.await(timeout, TimeUnit.SECONDS)) {
             throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Timeout waiting
" + timeout + " seconds for replica to become active.");
           }
         } finally {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f87a1471/solr/core/src/java/org/apache/solr/cloud/CreateShardCmd.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/CreateShardCmd.java b/solr/core/src/java/org/apache/solr/cloud/CreateShardCmd.java
index 70f964f..2d1c0bd 100644
--- a/solr/core/src/java/org/apache/solr/cloud/CreateShardCmd.java
+++ b/solr/core/src/java/org/apache/solr/cloud/CreateShardCmd.java
@@ -24,7 +24,6 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 import com.google.common.collect.ImmutableMap;
@@ -32,6 +31,7 @@ import org.apache.solr.client.solrj.cloud.autoscaling.AutoScalingConfig;
 import org.apache.solr.client.solrj.cloud.autoscaling.Policy;
 import org.apache.solr.client.solrj.cloud.autoscaling.PolicyHelper;
 import org.apache.solr.cloud.OverseerCollectionMessageHandler.Cmd;
+import org.apache.solr.common.SolrCloseableLatch;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.cloud.ClusterState;
 import org.apache.solr.common.cloud.DocCollection;
@@ -90,7 +90,7 @@ public class CreateShardCmd implements Cmd {
     ZkStateReader zkStateReader = ocmh.zkStateReader;
     boolean usePolicyFramework = usePolicyFramework(collection,ocmh);
     List<ReplicaPosition> positions = null;
-    CountDownLatch countDownLatch;
+    SolrCloseableLatch countDownLatch;
     try {
       if (usePolicyFramework) {
         if (collection.getPolicyName() != null) message.getProperties().put(Policy.POLICY,
collection.getPolicyName());
@@ -123,7 +123,7 @@ public class CreateShardCmd implements Cmd {
       ocmh.waitForNewShard(collectionName, sliceName);
 
       String async = message.getStr(ASYNC);
-      countDownLatch = new CountDownLatch(totalReplicas);
+      countDownLatch = new SolrCloseableLatch(totalReplicas, ocmh);
       for (ReplicaPosition position : positions) {
         String nodeName = position.node;
         String coreName = Assign.buildCoreName(ocmh.overseer.getSolrCloudManager().getDistribStateManager(),
collection, sliceName, position.type);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f87a1471/solr/core/src/java/org/apache/solr/cloud/LeaderRecoveryWatcher.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/LeaderRecoveryWatcher.java b/solr/core/src/java/org/apache/solr/cloud/LeaderRecoveryWatcher.java
index bf9a3fe..1eb4873 100644
--- a/solr/core/src/java/org/apache/solr/cloud/LeaderRecoveryWatcher.java
+++ b/solr/core/src/java/org/apache/solr/cloud/LeaderRecoveryWatcher.java
@@ -17,8 +17,8 @@
 package org.apache.solr.cloud;
 
 import java.util.Set;
-import java.util.concurrent.CountDownLatch;
 
+import org.apache.solr.common.SolrCloseableLatch;
 import org.apache.solr.common.cloud.CollectionStateWatcher;
 import org.apache.solr.common.cloud.DocCollection;
 import org.apache.solr.common.cloud.Replica;
@@ -33,7 +33,7 @@ public class LeaderRecoveryWatcher implements CollectionStateWatcher {
   String shardId;
   String replicaId;
   String targetCore;
-  CountDownLatch countDownLatch;
+  SolrCloseableLatch latch;
 
   /**
    * Watch for recovery of a replica
@@ -42,25 +42,25 @@ public class LeaderRecoveryWatcher implements CollectionStateWatcher {
    * @param shardId        shard id
    * @param replicaId      source replica name (coreNodeName)
    * @param targetCore     specific target core name - if null then any active replica will
do
-   * @param countDownLatch countdown when recovered
+   * @param latch countdown when recovered
    */
-  LeaderRecoveryWatcher(String collectionId, String shardId, String replicaId, String targetCore,
CountDownLatch countDownLatch) {
+  LeaderRecoveryWatcher(String collectionId, String shardId, String replicaId, String targetCore,
SolrCloseableLatch latch) {
     this.collectionId = collectionId;
     this.shardId = shardId;
     this.replicaId = replicaId;
     this.targetCore = targetCore;
-    this.countDownLatch = countDownLatch;
+    this.latch = latch;
   }
 
   @Override
   public boolean onStateChanged(Set<String> liveNodes, DocCollection collectionState)
{
     if (collectionState == null) { // collection has been deleted - don't wait
-      countDownLatch.countDown();
+      latch.countDown();
       return true;
     }
     Slice slice = collectionState.getSlice(shardId);
     if (slice == null) { // shard has been removed - don't wait
-      countDownLatch.countDown();
+      latch.countDown();
       return true;
     }
     for (Replica replica : slice.getReplicas()) {
@@ -77,7 +77,7 @@ public class LeaderRecoveryWatcher implements CollectionStateWatcher {
           continue;
         }
         if (replica.isActive(liveNodes)) { // recovered - stop waiting
-          countDownLatch.countDown();
+          latch.countDown();
           return true;
         }
       }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f87a1471/solr/core/src/java/org/apache/solr/cloud/MoveReplicaCmd.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/MoveReplicaCmd.java b/solr/core/src/java/org/apache/solr/cloud/MoveReplicaCmd.java
index 18bf968..4b479d2 100644
--- a/solr/core/src/java/org/apache/solr/cloud/MoveReplicaCmd.java
+++ b/solr/core/src/java/org/apache/solr/cloud/MoveReplicaCmd.java
@@ -22,9 +22,9 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Locale;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.solr.common.SolrCloseableLatch;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.cloud.ClusterState;
 import org.apache.solr.common.cloud.DocCollection;
@@ -194,7 +194,7 @@ public class MoveReplicaCmd implements Cmd{
         CoreAdminParams.NAME, newCoreName);
     if(async!=null) addReplicasProps.getProperties().put(ASYNC, async);
     NamedList addResult = new NamedList();
-    CountDownLatch countDownLatch = new CountDownLatch(1);
+    SolrCloseableLatch countDownLatch = new SolrCloseableLatch(1, ocmh);
     ActiveReplicaWatcher watcher = null;
     if (replica.equals(slice.getLeader()) || waitForFinalState) {
       watcher = new ActiveReplicaWatcher(coll.getName(), Collections.singletonList(replica.getName()),
null, countDownLatch);

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f87a1471/solr/core/src/java/org/apache/solr/cloud/Overseer.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/Overseer.java b/solr/core/src/java/org/apache/solr/cloud/Overseer.java
index b32158d..3b65d6f 100644
--- a/solr/core/src/java/org/apache/solr/cloud/Overseer.java
+++ b/solr/core/src/java/org/apache/solr/cloud/Overseer.java
@@ -38,6 +38,7 @@ import org.apache.solr.cloud.overseer.ReplicaMutator;
 import org.apache.solr.cloud.overseer.SliceMutator;
 import org.apache.solr.cloud.overseer.ZkStateWriter;
 import org.apache.solr.cloud.overseer.ZkWriteCommand;
+import org.apache.solr.common.SolrCloseable;
 import org.apache.solr.common.cloud.ClusterState;
 import org.apache.solr.common.cloud.SolrZkClient;
 import org.apache.solr.common.cloud.ZkNodeProps;
@@ -63,7 +64,7 @@ import static org.apache.solr.common.params.CommonParams.ID;
  * Cluster leader. Responsible for processing state updates, node assignments, creating/deleting
  * collections, shards, replicas and setting various properties.
  */
-public class Overseer implements Closeable {
+public class Overseer implements SolrCloseable {
   public static final String QUEUE_OPERATION = "operation";
 
   // System properties are used in tests to make them run fast
@@ -570,6 +571,11 @@ public class Overseer implements Closeable {
     assert ObjectReleaseTracker.release(this);
   }
 
+  @Override
+  public boolean isClosed() {
+    return closed;
+  }
+
   private void doClose() {
     
     if (updaterThread != null) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f87a1471/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java
b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java
index 08d6d10..da6722f 100644
--- a/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java
+++ b/solr/core/src/java/org/apache/solr/cloud/OverseerCollectionMessageHandler.java
@@ -44,6 +44,7 @@ import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
 import org.apache.solr.client.solrj.request.UpdateRequest;
 import org.apache.solr.client.solrj.response.UpdateResponse;
 import org.apache.solr.cloud.overseer.OverseerAction;
+import org.apache.solr.common.SolrCloseable;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.SolrException.ErrorCode;
 import org.apache.solr.common.cloud.ClusterState;
@@ -99,7 +100,7 @@ import static org.apache.solr.common.util.Utils.makeMap;
  * A {@link OverseerMessageHandler} that handles Collections API related
  * overseer messages.
  */
-public class OverseerCollectionMessageHandler implements OverseerMessageHandler , Closeable
{
+public class OverseerCollectionMessageHandler implements OverseerMessageHandler, SolrCloseable
{
 
   public static final String NUM_SLICES = "numShards";
 
@@ -169,6 +170,8 @@ public class OverseerCollectionMessageHandler implements OverseerMessageHandler
 
   final Map<CollectionAction, Cmd> commandMap;
 
+  private volatile boolean isClosed;
+
   public OverseerCollectionMessageHandler(ZkStateReader zkStateReader, String myId,
                                         final ShardHandlerFactory shardHandlerFactory,
                                         String adminPath,
@@ -181,6 +184,7 @@ public class OverseerCollectionMessageHandler implements OverseerMessageHandler
     this.myId = myId;
     this.stats = stats;
     this.overseer = overseer;
+    this.isClosed = false;
     commandMap = new ImmutableMap.Builder<CollectionAction, Cmd>()
         .put(REPLACENODE, new ReplaceNodeCmd(this))
         .put(DELETENODE, new DeleteNodeCmd(this))
@@ -978,6 +982,7 @@ public class OverseerCollectionMessageHandler implements OverseerMessageHandler
 
   @Override
   public void close() throws IOException {
+    this.isClosed = true;
     if (tpe != null) {
       if (!tpe.isShutdown()) {
         ExecutorUtil.shutdownAndAwaitTermination(tpe);
@@ -985,6 +990,11 @@ public class OverseerCollectionMessageHandler implements OverseerMessageHandler
     }
   }
 
+  @Override
+  public boolean isClosed() {
+    return isClosed;
+  }
+
   interface Cmd {
     void call(ClusterState state, ZkNodeProps message, NamedList results) throws Exception;
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f87a1471/solr/core/src/java/org/apache/solr/cloud/ReplaceNodeCmd.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/ReplaceNodeCmd.java b/solr/core/src/java/org/apache/solr/cloud/ReplaceNodeCmd.java
index 98d875f..e903091 100644
--- a/solr/core/src/java/org/apache/solr/cloud/ReplaceNodeCmd.java
+++ b/solr/core/src/java/org/apache/solr/cloud/ReplaceNodeCmd.java
@@ -25,10 +25,10 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 
+import org.apache.solr.common.SolrCloseableLatch;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.common.cloud.ClusterState;
 import org.apache.solr.common.cloud.CollectionStateWatcher;
@@ -94,9 +94,9 @@ public class ReplaceNodeCmd implements OverseerCollectionMessageHandler.Cmd
{
     List<ZkNodeProps> createdReplicas = new ArrayList<>();
 
     AtomicBoolean anyOneFailed = new AtomicBoolean(false);
-    CountDownLatch countDownLatch = new CountDownLatch(sourceReplicas.size());
+    SolrCloseableLatch countDownLatch = new SolrCloseableLatch(sourceReplicas.size(), ocmh);
 
-    CountDownLatch replicasToRecover = new CountDownLatch(numLeaders);
+    SolrCloseableLatch replicasToRecover = new SolrCloseableLatch(numLeaders, ocmh);
 
     for (ZkNodeProps sourceReplica : sourceReplicas) {
       NamedList nl = new NamedList();
@@ -169,7 +169,7 @@ public class ReplaceNodeCmd implements OverseerCollectionMessageHandler.Cmd
{
     }
     if (anyOneFailed.get()) {
       log.info("Failed to create some replicas. Cleaning up all replicas on target node");
-      CountDownLatch cleanupLatch = new CountDownLatch(createdReplicas.size());
+      SolrCloseableLatch cleanupLatch = new SolrCloseableLatch(createdReplicas.size(), ocmh);
       for (ZkNodeProps createdReplica : createdReplicas) {
         NamedList deleteResult = new NamedList();
         try {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f87a1471/solr/core/src/java/org/apache/solr/cloud/autoscaling/OverseerTriggerThread.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/cloud/autoscaling/OverseerTriggerThread.java
b/solr/core/src/java/org/apache/solr/cloud/autoscaling/OverseerTriggerThread.java
index dca7e68..574dcc5 100644
--- a/solr/core/src/java/org/apache/solr/cloud/autoscaling/OverseerTriggerThread.java
+++ b/solr/core/src/java/org/apache/solr/cloud/autoscaling/OverseerTriggerThread.java
@@ -36,6 +36,7 @@ import org.apache.solr.client.solrj.cloud.autoscaling.BadVersionException;
 import org.apache.solr.client.solrj.cloud.autoscaling.DistribStateManager;
 import org.apache.solr.client.solrj.cloud.autoscaling.SolrCloudManager;
 import org.apache.solr.client.solrj.cloud.autoscaling.TriggerEventType;
+import org.apache.solr.common.SolrCloseable;
 import org.apache.solr.common.cloud.ZkStateReader;
 import org.apache.solr.common.util.IOUtils;
 import org.apache.solr.common.util.Utils;
@@ -53,7 +54,7 @@ import static org.apache.solr.common.cloud.ZkStateReader.SOLR_AUTOSCALING_CONF_P
  * Overseer thread responsible for reading triggers from zookeeper and
  * adding/removing them from {@link ScheduledTriggers}
  */
-public class OverseerTriggerThread implements Runnable, Closeable {
+public class OverseerTriggerThread implements Runnable, SolrCloseable {
 
   private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
@@ -103,6 +104,11 @@ public class OverseerTriggerThread implements Runnable, Closeable {
   }
 
   @Override
+  public boolean isClosed() {
+    return isClosed;
+  }
+
+  @Override
   public void run() {
     int lastZnodeVersion = znodeVersion;
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f87a1471/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/autoscaling/SolrCloudManager.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/autoscaling/SolrCloudManager.java
b/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/autoscaling/SolrCloudManager.java
index 5b38e88..726c2c6 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/autoscaling/SolrCloudManager.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/cloud/autoscaling/SolrCloudManager.java
@@ -17,7 +17,6 @@
 
 package org.apache.solr.client.solrj.cloud.autoscaling;
 
-import java.io.Closeable;
 import java.io.IOException;
 import java.util.Map;
 
@@ -25,13 +24,14 @@ import org.apache.solr.client.solrj.SolrRequest;
 import org.apache.solr.client.solrj.SolrResponse;
 import org.apache.solr.client.solrj.cloud.DistributedQueueFactory;
 import org.apache.solr.client.solrj.impl.ClusterStateProvider;
+import org.apache.solr.common.SolrCloseable;
 
 /**
  * This interface abstracts the access to a SolrCloud cluster, including interactions with
Zookeeper, Solr
  * and generic HTTP calls.
  * <p>This abstraction should be used when possible instead of directly referencing
ZK, Solr and HTTP.</p>
  */
-public interface SolrCloudManager extends Closeable {
+public interface SolrCloudManager extends SolrCloseable {
 
   ClusterStateProvider getClusterStateProvider();
 
@@ -53,8 +53,4 @@ public interface SolrCloudManager extends Closeable {
   default void close() {
 
   }
-
-  default boolean isClosed() {
-    return false;
-  }
 }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f87a1471/solr/solrj/src/java/org/apache/solr/common/SolrCloseable.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/common/SolrCloseable.java b/solr/solrj/src/java/org/apache/solr/common/SolrCloseable.java
new file mode 100644
index 0000000..130e5ab
--- /dev/null
+++ b/solr/solrj/src/java/org/apache/solr/common/SolrCloseable.java
@@ -0,0 +1,30 @@
+/*
+ * 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.common;
+
+import java.io.Closeable;
+
+/**
+ * A {@link Closeable} that also allows checking whether it's been closed.
+ */
+public interface SolrCloseable extends Closeable {
+
+  default boolean isClosed() {
+    return false;
+  }
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/f87a1471/solr/solrj/src/java/org/apache/solr/common/SolrCloseableLatch.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/common/SolrCloseableLatch.java b/solr/solrj/src/java/org/apache/solr/common/SolrCloseableLatch.java
new file mode 100644
index 0000000..c2b1762
--- /dev/null
+++ b/solr/solrj/src/java/org/apache/solr/common/SolrCloseableLatch.java
@@ -0,0 +1,65 @@
+/*
+ * 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.common;
+
+import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This class mimicks the operation of {@link java.util.concurrent.CountDownLatch}, but it
also
+ * periodically checks the state of the provided {@link SolrCloseable} and terminates the
wait
+ * if it's closed by throwing an {@link InterruptedException}.
+ */
+public class SolrCloseableLatch {
+
+  private final SolrCloseable closeable;
+  private final CountDownLatch latch;
+
+  public SolrCloseableLatch(int count, SolrCloseable closeable) {
+    Objects.requireNonNull(closeable);
+    this.closeable = closeable;
+    this.latch = new CountDownLatch(count);
+  }
+
+  public void await() throws InterruptedException {
+    await(Long.MAX_VALUE, TimeUnit.SECONDS);
+  }
+
+  public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
+    timeout = unit.toMillis(timeout);
+    while (timeout > 0) {
+      if (latch.await(100, TimeUnit.MILLISECONDS)) {
+        return true;
+      }
+      if (closeable.isClosed()) {
+        throw new InterruptedException(closeable + " has been closed.");
+      }
+      timeout -= 100;
+    }
+    return false;
+  }
+
+  public void countDown() {
+    latch.countDown();
+  }
+
+  public long getCount() {
+    return latch.getCount();
+  }
+}


Mime
View raw message