|
@@ -41,6 +41,7 @@ import org.elasticsearch.common.CheckedRunnable;
|
|
|
import org.elasticsearch.common.Randomness;
|
|
|
import org.elasticsearch.common.SuppressForbidden;
|
|
|
import org.elasticsearch.common.UUIDs;
|
|
|
+import org.elasticsearch.common.collect.Tuple;
|
|
|
import org.elasticsearch.common.io.FileSystemUtils;
|
|
|
import org.elasticsearch.common.lease.Releasable;
|
|
|
import org.elasticsearch.common.settings.Setting;
|
|
@@ -786,6 +787,11 @@ public final class NodeEnvironment implements Closeable {
|
|
|
shardLock.release();
|
|
|
logger.trace("released shard lock for [{}]", shardId);
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void setDetails(String details) {
|
|
|
+ shardLock.setDetails(details);
|
|
|
+ }
|
|
|
};
|
|
|
}
|
|
|
|
|
@@ -817,13 +823,13 @@ public final class NodeEnvironment implements Closeable {
|
|
|
*/
|
|
|
private final Semaphore mutex = new Semaphore(1);
|
|
|
private int waitCount = 1; // guarded by shardLocks
|
|
|
- private String lockDetails;
|
|
|
private final ShardId shardId;
|
|
|
+ private volatile Tuple<Long, String> lockDetails;
|
|
|
|
|
|
InternalShardLock(final ShardId shardId, final String details) {
|
|
|
this.shardId = shardId;
|
|
|
mutex.acquireUninterruptibly();
|
|
|
- lockDetails = details;
|
|
|
+ lockDetails = Tuple.tuple(System.nanoTime(), details);
|
|
|
}
|
|
|
|
|
|
protected void release() {
|
|
@@ -854,17 +860,23 @@ public final class NodeEnvironment implements Closeable {
|
|
|
void acquire(long timeoutInMillis, final String details) throws ShardLockObtainFailedException {
|
|
|
try {
|
|
|
if (mutex.tryAcquire(timeoutInMillis, TimeUnit.MILLISECONDS)) {
|
|
|
- lockDetails = details;
|
|
|
+ setDetails(details);
|
|
|
} else {
|
|
|
+ final Tuple<Long, String> lockDetails = this.lockDetails; // single volatile read
|
|
|
throw new ShardLockObtainFailedException(shardId,
|
|
|
- "obtaining shard lock timed out after " + timeoutInMillis + "ms, previous lock details: [" + lockDetails +
|
|
|
- "] trying to lock for [" + details + "]");
|
|
|
+ "obtaining shard lock for [" + details + "] timed out after [" + timeoutInMillis +
|
|
|
+ "ms], lock already held for [" + lockDetails.v2() + "] with age [" +
|
|
|
+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - lockDetails.v1()) + "ms]");
|
|
|
}
|
|
|
} catch (InterruptedException e) {
|
|
|
Thread.currentThread().interrupt();
|
|
|
throw new ShardLockObtainFailedException(shardId, "thread interrupted while trying to obtain shard lock", e);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ public void setDetails(String details) {
|
|
|
+ lockDetails = Tuple.tuple(System.nanoTime(), details);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
public boolean hasNodeFile() {
|