|
@@ -664,6 +664,7 @@ public class ShortCircuitCache implements Closeable {
|
|
unref(replica);
|
|
unref(replica);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ static final int FETCH_OR_CREATE_RETRY_TIMES = 3;
|
|
/**
|
|
/**
|
|
* Fetch or create a replica.
|
|
* Fetch or create a replica.
|
|
*
|
|
*
|
|
@@ -678,11 +679,11 @@ public class ShortCircuitCache implements Closeable {
|
|
*/
|
|
*/
|
|
public ShortCircuitReplicaInfo fetchOrCreate(ExtendedBlockId key,
|
|
public ShortCircuitReplicaInfo fetchOrCreate(ExtendedBlockId key,
|
|
ShortCircuitReplicaCreator creator) {
|
|
ShortCircuitReplicaCreator creator) {
|
|
- Waitable<ShortCircuitReplicaInfo> newWaitable = null;
|
|
|
|
|
|
+ Waitable<ShortCircuitReplicaInfo> newWaitable;
|
|
lock.lock();
|
|
lock.lock();
|
|
try {
|
|
try {
|
|
ShortCircuitReplicaInfo info = null;
|
|
ShortCircuitReplicaInfo info = null;
|
|
- do {
|
|
|
|
|
|
+ for (int i = 0; i < FETCH_OR_CREATE_RETRY_TIMES; i++){
|
|
if (closed) {
|
|
if (closed) {
|
|
LOG.trace("{}: can't fethchOrCreate {} because the cache is closed.",
|
|
LOG.trace("{}: can't fethchOrCreate {} because the cache is closed.",
|
|
this, key);
|
|
this, key);
|
|
@@ -692,11 +693,12 @@ public class ShortCircuitCache implements Closeable {
|
|
if (waitable != null) {
|
|
if (waitable != null) {
|
|
try {
|
|
try {
|
|
info = fetch(key, waitable);
|
|
info = fetch(key, waitable);
|
|
|
|
+ break;
|
|
} catch (RetriableException e) {
|
|
} catch (RetriableException e) {
|
|
LOG.debug("{}: retrying {}", this, e.getMessage());
|
|
LOG.debug("{}: retrying {}", this, e.getMessage());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- } while (false);
|
|
|
|
|
|
+ }
|
|
if (info != null) return info;
|
|
if (info != null) return info;
|
|
// We need to load the replica ourselves.
|
|
// We need to load the replica ourselves.
|
|
newWaitable = new Waitable<>(lock.newCondition());
|
|
newWaitable = new Waitable<>(lock.newCondition());
|
|
@@ -717,7 +719,8 @@ public class ShortCircuitCache implements Closeable {
|
|
*
|
|
*
|
|
* @throws RetriableException If the caller needs to retry.
|
|
* @throws RetriableException If the caller needs to retry.
|
|
*/
|
|
*/
|
|
- private ShortCircuitReplicaInfo fetch(ExtendedBlockId key,
|
|
|
|
|
|
+ @VisibleForTesting // ONLY for testing
|
|
|
|
+ protected ShortCircuitReplicaInfo fetch(ExtendedBlockId key,
|
|
Waitable<ShortCircuitReplicaInfo> waitable) throws RetriableException {
|
|
Waitable<ShortCircuitReplicaInfo> waitable) throws RetriableException {
|
|
// Another thread is already in the process of loading this
|
|
// Another thread is already in the process of loading this
|
|
// ShortCircuitReplica. So we simply wait for it to complete.
|
|
// ShortCircuitReplica. So we simply wait for it to complete.
|