-
Notifications
You must be signed in to change notification settings - Fork 24.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Clarify allocation explain if random shard chosen #75670
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
|
||
package org.elasticsearch.action.admin.cluster.allocation; | ||
|
||
import org.elasticsearch.Version; | ||
import org.elasticsearch.cluster.ClusterInfo; | ||
import org.elasticsearch.cluster.node.DiscoveryNode; | ||
import org.elasticsearch.cluster.routing.ShardRouting; | ||
|
@@ -36,15 +37,27 @@ | |
*/ | ||
public final class ClusterAllocationExplanation implements ToXContentObject, Writeable { | ||
|
||
static final String NO_SHARD_SPECIFIED_MESSAGE = "No shard was specified in the explain API request, so this response " + | ||
"explains a randomly chosen unassigned shard. There may be other unassigned shards in this cluster which cannot be assigned for " + | ||
"different reasons. It may not be possible to assign this shard until one of the other shards is assigned correctly. To explain " + | ||
"the allocation of other shards (whether assigned or unassigned) you must specify the target shard in the request to this API."; | ||
|
||
private final boolean specificShard; | ||
private final ShardRouting shardRouting; | ||
private final DiscoveryNode currentNode; | ||
private final DiscoveryNode relocationTargetNode; | ||
private final ClusterInfo clusterInfo; | ||
private final ShardAllocationDecision shardAllocationDecision; | ||
|
||
public ClusterAllocationExplanation(ShardRouting shardRouting, @Nullable DiscoveryNode currentNode, | ||
@Nullable DiscoveryNode relocationTargetNode, @Nullable ClusterInfo clusterInfo, | ||
ShardAllocationDecision shardAllocationDecision) { | ||
public ClusterAllocationExplanation( | ||
boolean specificShard, | ||
ShardRouting shardRouting, | ||
@Nullable DiscoveryNode currentNode, | ||
@Nullable DiscoveryNode relocationTargetNode, | ||
@Nullable ClusterInfo clusterInfo, | ||
ShardAllocationDecision shardAllocationDecision) { | ||
|
||
this.specificShard = specificShard; | ||
this.shardRouting = shardRouting; | ||
this.currentNode = currentNode; | ||
this.relocationTargetNode = relocationTargetNode; | ||
|
@@ -53,6 +66,11 @@ public ClusterAllocationExplanation(ShardRouting shardRouting, @Nullable Discove | |
} | ||
|
||
public ClusterAllocationExplanation(StreamInput in) throws IOException { | ||
if (in.getVersion().onOrAfter(Version.V_8_0_0)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume BwC stands for backwards compatibility, is that correct? (I've seen it several times already, but I figured I should finally confirm). I assume that adding an extra field in the API response is not a breaking change, is that correct? I am also assuming we are being extra cautious and not introducing it in 7.x, but we could have technically done so, had we wanted to, is that correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's correct, BwC is short for backwards compatibility. Adding an extra field to the response is indeed not considered a breaking change, we expect clients to skip fields they don't recognise. The labels on the PR indicate how this will be backported, so yes this will go into 7.x. However we have to start out with the change being 8.0-only because we need it to pass all the mixed-version tests in CI first. We'll then backport it and (simultaneously) adjust the version on this line to match. It's quite a complex dance. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it, @DaveCTurner, thanks a lot for the context. |
||
this.specificShard = in.readBoolean(); | ||
} else { | ||
this.specificShard = true; // suppress "this is a random shard" warning in BwC situations | ||
} | ||
this.shardRouting = new ShardRouting(in); | ||
this.currentNode = in.readOptionalWriteable(DiscoveryNode::new); | ||
this.relocationTargetNode = in.readOptionalWriteable(DiscoveryNode::new); | ||
|
@@ -62,13 +80,20 @@ public ClusterAllocationExplanation(StreamInput in) throws IOException { | |
|
||
@Override | ||
public void writeTo(StreamOutput out) throws IOException { | ||
if (out.getVersion().onOrAfter(Version.V_8_0_0)) { | ||
out.writeBoolean(specificShard); | ||
} // else suppress "this is a random shard" warning in BwC situations | ||
shardRouting.writeTo(out); | ||
out.writeOptionalWriteable(currentNode); | ||
out.writeOptionalWriteable(relocationTargetNode); | ||
out.writeOptionalWriteable(clusterInfo); | ||
shardAllocationDecision.writeTo(out); | ||
} | ||
|
||
public boolean isSpecificShard() { | ||
return specificShard; | ||
} | ||
|
||
/** | ||
* Returns the shard that the explanation is about. | ||
*/ | ||
|
@@ -131,6 +156,9 @@ public ShardAllocationDecision getShardAllocationDecision() { | |
|
||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { | ||
builder.startObject(); { | ||
if (isSpecificShard() == false) { | ||
builder.field("note", NO_SHARD_SPECIFIED_MESSAGE); | ||
} | ||
builder.field("index", shardRouting.getIndexName()); | ||
builder.field("shard", shardRouting.getId()); | ||
builder.field("primary", shardRouting.primary()); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. I assume that POST should have been documented already but we had missed it, but please correct me if that is not the case. If that is the case, should we also be including examples for POST, similar to the ones we have for GET, or a note that they are equivalent?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The convention is that all
GET
APIs that take a body should also work the same withPOST
, see e.g. https://www.elastic.co/guide/en/elasticsearch/reference/current/api-conventions.html#api-conventionsI've added this here to emphasise that you can send a request with a body - some tooling makes it hard to execute a
GET
with a body, you have to switch it intoPOST
modelThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it, @DaveCTurner thanks for clarifying. Good to know there is general guidance in the documentation already.