You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ab...@apache.org on 2017/10/23 10:50:48 UTC
lucene-solr:jira/solr-11320: SOLR-11320: Add SolrCloseableLatch that
can be interrupted when a SolrCloseable is closed.
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();
+ }
+}