Add `prefer_local` flag to analyze and percolate request, closes #625.
This commit is contained in:
parent
ff347858c5
commit
38d10d19bc
|
@ -79,6 +79,15 @@ public class AnalyzeRequest extends SingleCustomOperationRequest {
|
|||
return this.analyzer;
|
||||
}
|
||||
|
||||
/**
|
||||
* if this operation hits a node with a local relevant shard, should it be preferred
|
||||
* to be executed on, or just do plain round robin. Defaults to <tt>true</tt>
|
||||
*/
|
||||
@Override public AnalyzeRequest preferLocal(boolean preferLocal) {
|
||||
super.preferLocal(preferLocal);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public ActionRequestValidationException validate() {
|
||||
ActionRequestValidationException validationException = super.validate();
|
||||
if (index == null) {
|
||||
|
|
|
@ -75,7 +75,7 @@ public class TransportAnalyzeAction extends TransportSingleCustomOperationAction
|
|||
|
||||
@Override protected ShardsIterator shards(ClusterState clusterState, AnalyzeRequest request) {
|
||||
request.index(clusterState.metaData().concreteIndex(request.index()));
|
||||
return clusterState.routingTable().index(request.index()).allShardsIt();
|
||||
return clusterState.routingTable().index(request.index()).randomAllShardsIt();
|
||||
}
|
||||
|
||||
@Override protected AnalyzeResponse shardOperation(AnalyzeRequest request, int shardId) throws ElasticSearchException {
|
||||
|
|
|
@ -150,6 +150,15 @@ public class PercolateRequest extends SingleCustomOperationRequest {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* if this operation hits a node with a local relevant shard, should it be preferred
|
||||
* to be executed on, or just do plain round robin. Defaults to <tt>true</tt>
|
||||
*/
|
||||
@Override public PercolateRequest preferLocal(boolean preferLocal) {
|
||||
super.preferLocal(preferLocal);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override public ActionRequestValidationException validate() {
|
||||
ActionRequestValidationException validationException = super.validate();
|
||||
if (index == null) {
|
||||
|
|
|
@ -65,7 +65,7 @@ public class TransportPercolateAction extends TransportSingleCustomOperationActi
|
|||
|
||||
@Override protected ShardsIterator shards(ClusterState clusterState, PercolateRequest request) {
|
||||
request.index(clusterState.metaData().concreteIndex(request.index()));
|
||||
return clusterState.routingTable().index(request.index()).allShardsIt();
|
||||
return clusterState.routingTable().index(request.index()).randomAllShardsIt();
|
||||
}
|
||||
|
||||
@Override protected PercolateResponse shardOperation(PercolateRequest request, int shardId) throws ElasticSearchException {
|
||||
|
|
|
@ -33,6 +33,7 @@ public abstract class SingleCustomOperationRequest implements ActionRequest {
|
|||
|
||||
private boolean threadedListener = false;
|
||||
private boolean threadedOperation = true;
|
||||
private boolean preferLocal = true;
|
||||
|
||||
protected SingleCustomOperationRequest() {
|
||||
}
|
||||
|
@ -68,15 +69,34 @@ public abstract class SingleCustomOperationRequest implements ActionRequest {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* if this operation hits a node with a local relevant shard, should it be preferred
|
||||
* to be executed on, or just do plain round robin. Defaults to <tt>true</tt>
|
||||
*/
|
||||
public SingleCustomOperationRequest preferLocal(boolean preferLocal) {
|
||||
this.preferLocal = preferLocal;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* if this operation hits a node with a local relevant shard, should it be preferred
|
||||
* to be executed on, or just do plain round robin. Defaults to <tt>true</tt>
|
||||
*/
|
||||
public boolean preferLocalShard() {
|
||||
return this.preferLocal;
|
||||
}
|
||||
|
||||
public void beforeLocalFork() {
|
||||
|
||||
}
|
||||
|
||||
@Override public void readFrom(StreamInput in) throws IOException {
|
||||
// no need to pass threading over the network, they are always false when coming throw a thread pool
|
||||
preferLocal = in.readBoolean();
|
||||
}
|
||||
|
||||
@Override public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeBoolean(preferLocal);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -116,40 +116,44 @@ public abstract class TransportSingleCustomOperationAction<Request extends Singl
|
|||
* First get should try and use a shard that exists on a local node for better performance
|
||||
*/
|
||||
private void performFirst() {
|
||||
while (shardsIt.hasNextActive()) {
|
||||
final ShardRouting shard = shardsIt.nextActive();
|
||||
if (shard.currentNodeId().equals(nodes.localNodeId())) {
|
||||
if (request.operationThreaded()) {
|
||||
request.beforeLocalFork();
|
||||
threadPool.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());
|
||||
if (request.listenerThreaded()) {
|
||||
threadPool.execute(new Runnable() {
|
||||
@Override public void run() {
|
||||
if (request.preferLocalShard()) {
|
||||
while (shardsIt.hasNextActive()) {
|
||||
final ShardRouting shard = shardsIt.nextActive();
|
||||
if (shard.currentNodeId().equals(nodes.localNodeId())) {
|
||||
if (request.operationThreaded()) {
|
||||
request.beforeLocalFork();
|
||||
threadPool.execute(new Runnable() {
|
||||
@Override public void run() {
|
||||
try {
|
||||
Response response = shardOperation(request, shard.id());
|
||||
listener.onResponse(response);
|
||||
} catch (Exception e) {
|
||||
onFailure(shard, e);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
listener.onResponse(response);
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
onFailure(shard, e);
|
||||
} else {
|
||||
try {
|
||||
final Response response = shardOperation(request, shard.id());
|
||||
if (request.listenerThreaded()) {
|
||||
threadPool.execute(new Runnable() {
|
||||
@Override public void run() {
|
||||
listener.onResponse(response);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
listener.onResponse(response);
|
||||
}
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
onFailure(shard, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
perform(null);
|
||||
}
|
||||
if (!shardsIt.hasNextActive()) {
|
||||
// no local node get, go remote
|
||||
|
@ -162,7 +166,41 @@ public abstract class TransportSingleCustomOperationAction<Request extends Singl
|
|||
while (shardsIt.hasNextActive()) {
|
||||
final ShardRouting shard = shardsIt.nextActive();
|
||||
// no need to check for local nodes, we tried them already in performFirstGet
|
||||
if (!shard.currentNodeId().equals(nodes.localNodeId())) {
|
||||
if (shard.currentNodeId().equals(nodes.localNodeId())) {
|
||||
// we don't prefer local shard, so try and do it here
|
||||
if (!request.preferLocalShard()) {
|
||||
if (request.operationThreaded()) {
|
||||
request.beforeLocalFork();
|
||||
threadPool.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());
|
||||
if (request.listenerThreaded()) {
|
||||
threadPool.execute(new Runnable() {
|
||||
@Override public void run() {
|
||||
listener.onResponse(response);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
listener.onResponse(response);
|
||||
}
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
onFailure(shard, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DiscoveryNode node = nodes.get(shard.currentNodeId());
|
||||
transportService.sendRequest(node, transportShardAction(), new ShardSingleOperationRequest(request, shard.id()), new BaseTransportResponseHandler<Response>() {
|
||||
@Override public Response newInstance() {
|
||||
|
|
|
@ -44,6 +44,15 @@ public class AnalyzeRequestBuilder extends BaseIndicesRequestBuilder<AnalyzeRequ
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* if this operation hits a node with a local relevant shard, should it be preferred
|
||||
* to be executed on, or just do plain round robin. Defaults to <tt>true</tt>
|
||||
*/
|
||||
public AnalyzeRequestBuilder setPreferLocal(boolean preferLocal) {
|
||||
request.preferLocal(preferLocal);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override protected void doExecute(ActionListener<AnalyzeResponse> listener) {
|
||||
client.analyze(request, listener);
|
||||
}
|
||||
|
|
|
@ -128,6 +128,15 @@ public class PercolateRequestBuilder extends BaseRequestBuilder<PercolateRequest
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* if this operation hits a node with a local relevant shard, should it be preferred
|
||||
* to be executed on, or just do plain round robin. Defaults to <tt>true</tt>
|
||||
*/
|
||||
public PercolateRequestBuilder setPreferLocal(boolean preferLocal) {
|
||||
request.preferLocal(preferLocal);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls if the operation will be executed on a separate thread when executed locally. Defaults
|
||||
* to <tt>true</tt> when running in embedded mode.
|
||||
|
|
|
@ -153,7 +153,7 @@ public class IndexRoutingTable implements Iterable<IndexShardRoutingTable> {
|
|||
/**
|
||||
* An iterator over all shards (including replicas).
|
||||
*/
|
||||
public ShardsIterator allShardsIt() {
|
||||
public ShardsIterator randomAllShardsIt() {
|
||||
return new PlainShardsIterator(allShards, Math.abs(counter.incrementAndGet()));
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ public class RestAnalyzeAction extends BaseRestHandler {
|
|||
}
|
||||
|
||||
AnalyzeRequest analyzeRequest = new AnalyzeRequest(request.param("index"), text);
|
||||
analyzeRequest.preferLocal(request.paramAsBoolean("prefer_local", analyzeRequest.preferLocalShard()));
|
||||
analyzeRequest.analyzer(request.param("analyzer"));
|
||||
client.admin().indices().analyze(analyzeRequest, new ActionListener<AnalyzeResponse>() {
|
||||
@Override public void onResponse(AnalyzeResponse response) {
|
||||
|
|
|
@ -55,6 +55,7 @@ public class RestPercolateAction extends BaseRestHandler {
|
|||
// we don't spawn, then fork if local
|
||||
percolateRequest.operationThreaded(true);
|
||||
|
||||
percolateRequest.preferLocal(request.paramAsBoolean("prefer_local", percolateRequest.preferLocalShard()));
|
||||
client.percolate(percolateRequest, new ActionListener<PercolateResponse>() {
|
||||
@Override public void onResponse(PercolateResponse response) {
|
||||
try {
|
||||
|
|
|
@ -101,11 +101,21 @@ public class SimplePercolatorTests extends AbstractNodesTests {
|
|||
.execute().actionGet();
|
||||
client.admin().cluster().prepareHealth().setWaitForGreenStatus().setWaitForActiveShards(4).execute().actionGet();
|
||||
|
||||
PercolateResponse percolate = client.preparePercolate("test").setSource(jsonBuilder().startObject().startObject("doc").startObject("type1")
|
||||
.field("field1", "value1")
|
||||
.endObject().endObject().endObject())
|
||||
.execute().actionGet();
|
||||
assertThat(percolate.matches().size(), equalTo(1));
|
||||
for (int i = 0; i < 10; i++) {
|
||||
PercolateResponse percolate = client.preparePercolate("test").setSource(jsonBuilder().startObject().startObject("doc").startObject("type1")
|
||||
.field("field1", "value1")
|
||||
.endObject().endObject().endObject())
|
||||
.execute().actionGet();
|
||||
assertThat(percolate.matches().size(), equalTo(1));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
PercolateResponse percolate = client.preparePercolate("test").setPreferLocal(false).setSource(jsonBuilder().startObject().startObject("doc").startObject("type1")
|
||||
.field("field1", "value1")
|
||||
.endObject().endObject().endObject())
|
||||
.execute().actionGet();
|
||||
assertThat(percolate.matches().size(), equalTo(1));
|
||||
}
|
||||
}
|
||||
|
||||
@Test public void dynamicAddingRemovingQueries() throws Exception {
|
||||
|
|
Loading…
Reference in New Issue