Get API: Will always prefer first local execution, regardless of the preference, closes #1153.

This commit is contained in:
Shay Banon 2011-07-24 20:33:49 +03:00
parent b31f68a0eb
commit 5ce42b337d
1 changed files with 48 additions and 66 deletions

View File

@ -30,6 +30,7 @@ import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.cluster.node.DiscoveryNodes; import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.routing.ShardIterator; import org.elasticsearch.cluster.routing.ShardIterator;
import org.elasticsearch.cluster.routing.ShardRouting; import org.elasticsearch.cluster.routing.ShardRouting;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.io.stream.StreamInput; import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Streamable; import org.elasticsearch.common.io.stream.Streamable;
@ -117,7 +118,7 @@ public abstract class TransportShardSingleOperationAction<Request extends Single
} }
public void start() { public void start() {
performFirst(); perform(null);
} }
private void onFailure(ShardRouting shardRouting, Exception e) { private void onFailure(ShardRouting shardRouting, Exception e) {
@ -127,71 +128,9 @@ public abstract class TransportShardSingleOperationAction<Request extends Single
perform(e); perform(e);
} }
/** private void perform(@Nullable final Exception lastException) {
* First get should try and use a shard that exists on a local node for better performance final ShardRouting shardRouting = shardIt.nextActiveOrNull();
*/ if (shardRouting == null) {
private void performFirst() {
while (shardIt.hasNextActive()) {
final ShardRouting shard = shardIt.nextActive();
if (shard.currentNodeId().equals(nodes.localNodeId())) {
if (request.operationThreaded()) {
threadPool.executor(executor).execute(new Runnable() {
@Override public void run() {
try {
Response response = shardOperation(request, shard.id());
listener.onResponse(response);
} catch (Exception e) {
onFailure(shard, e);
}
}
});
return;
} else {
try {
final Response response = shardOperation(request, shard.id());
listener.onResponse(response);
return;
} catch (Exception e) {
onFailure(shard, e);
}
}
}
}
if (!shardIt.hasNextActive()) {
// no local node get, go remote
shardIt.reset();
perform(null);
}
}
private void perform(final Exception lastException) {
while (shardIt.hasNextActive()) {
final ShardRouting shard = shardIt.nextActive();
// no need to check for local nodes, we tried them already in performFirstGet
if (!shard.currentNodeId().equals(nodes.localNodeId())) {
DiscoveryNode node = nodes.get(shard.currentNodeId());
transportService.sendRequest(node, transportShardAction, new ShardSingleOperationRequest(request, shard.id()), new BaseTransportResponseHandler<Response>() {
@Override public Response newInstance() {
return newResponse();
}
@Override public String executor() {
return ThreadPool.Names.SAME;
}
@Override public void handleResponse(final Response response) {
listener.onResponse(response);
}
@Override public void handleException(TransportException exp) {
onFailure(shard, exp);
}
});
return;
}
}
if (!shardIt.hasNextActive()) {
Exception failure = lastException; Exception failure = lastException;
if (failure == null) { if (failure == null) {
failure = new NoShardAvailableActionException(shardIt.shardId(), "No shard available for [" + request + "]"); failure = new NoShardAvailableActionException(shardIt.shardId(), "No shard available for [" + request + "]");
@ -201,6 +140,49 @@ public abstract class TransportShardSingleOperationAction<Request extends Single
} }
} }
listener.onFailure(failure); listener.onFailure(failure);
return;
}
if (shardRouting.currentNodeId().equals(nodes.localNodeId())) {
if (request.operationThreaded()) {
threadPool.executor(executor).execute(new Runnable() {
@Override public void run() {
try {
Response response = shardOperation(request, shardRouting.id());
listener.onResponse(response);
} catch (Exception e) {
onFailure(shardRouting, e);
}
}
});
} else {
try {
final Response response = shardOperation(request, shardRouting.id());
listener.onResponse(response);
} catch (Exception e) {
onFailure(shardRouting, e);
}
}
} else {
DiscoveryNode node = nodes.get(shardRouting.currentNodeId());
transportService.sendRequest(node, transportShardAction, new ShardSingleOperationRequest(request, shardRouting.id()), new BaseTransportResponseHandler<Response>() {
@Override public Response newInstance() {
return newResponse();
}
@Override public String executor() {
return ThreadPool.Names.SAME;
}
@Override public void handleResponse(final Response response) {
listener.onResponse(response);
}
@Override public void handleException(TransportException exp) {
onFailure(shardRouting, exp);
}
});
} }
} }
} }