SOLR-12923: fix SimClusterStateProvider to use lock.lockInterruptibly() exclusively, and make SimCloudManager's Callable checks tollerant of Callables that may have failed related to interrupts w/o explicitly throwing InterruptedException

This commit is contained in:
Chris Hostetter 2019-03-15 12:06:53 -07:00
parent c79aeee5f9
commit 1a54c6b19d
2 changed files with 29 additions and 9 deletions

View File

@ -967,6 +967,21 @@ public class SimCloudManager implements SolrCloudManager {
log.warn("Callable interupted", ignored);
throw ignored;
} catch (Throwable t) {
// be forgiving of errors that occured as a result of interuption, even if
// the inner Callable didn't realize it...
if (Thread.currentThread().isInterrupted()) {
log.warn("Callable interupted w/o noticing", t);
throw t;
}
Throwable cause = t;
while ((cause = cause.getCause()) != null) {
if (cause instanceof InterruptedException) {
log.warn("Callable threw wrapped InterruptedException", t);
throw t;
}
}
// in all other situations, this is a problem that should be tracked in the failCounter
failCounter.incrementAndGet();
log.error("Callable failed", t);
throw t;

View File

@ -18,6 +18,7 @@
package org.apache.solr.cloud.autoscaling.sim;
import java.io.IOException;
import java.lang.InterruptedException;
import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.Arrays;
@ -190,7 +191,7 @@ public class SimClusterStateProvider implements ClusterStateProvider {
* @param initialState initial cluster state
*/
public void simSetClusterState(ClusterState initialState) throws Exception {
lock.lock();
lock.lockInterruptibly();
try {
collProperties.clear();
sliceProperties.clear();
@ -2148,20 +2149,24 @@ public class SimClusterStateProvider implements ClusterStateProvider {
@Override
public ClusterState getClusterState() throws IOException {
ensureNotClosed();
lock.lock();
try {
Map<String, DocCollection> states = getCollectionStates();
ClusterState state = new ClusterState(clusterStateVersion, liveNodes.get(), states);
return state;
} finally {
lock.unlock();
lock.lockInterruptibly();
try {
Map<String, DocCollection> states = getCollectionStates();
ClusterState state = new ClusterState(clusterStateVersion, liveNodes.get(), states);
return state;
} finally {
lock.unlock();
}
} catch (InterruptedException e) {
throw new IOException(e);
}
}
// this method uses a simple cache in collectionsStatesRef. Operations that modify
// cluster state should always reset this cache so that the changes become visible
private Map<String, DocCollection> getCollectionStates() throws IOException {
lock.lock();
private Map<String, DocCollection> getCollectionStates() throws IOException, InterruptedException {
lock.lockInterruptibly();
try {
Map<String, DocCollection> collectionStates = collectionsStatesRef.get();
if (collectionStates != null) {