-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Introduce TransportGetFromTranslogAction #95998
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
Introduce TransportGetFromTranslogAction #95998
Conversation
Pinging @elastic/es-distributed (Team:Distributed) |
An earlier version of this has been already reviewed: https://github.com/elastic/elasticsearch/pull/93976/files#diff-8daf8bbe7449a3292228747c41ac167377916cc2ee31621eedfb56dd6d3465ee. |
Engine engine = indexShard.getEngineOrNull(); | ||
if (engine == null) { | ||
listener.onFailure(new AlreadyClosedException("engine closed")); | ||
return; | ||
} |
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.
I wonder if this is really needed because ShardGetService.getFromTranslog()
uses getEngine()
at some point and that will throw in case of a closed engine. I think we can do this only if the result
of the getFromTranslog
is null?
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.
You're right, that's not needed there. Slightly outdated code! I've moved it to when result is null.
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Show resolved
Hide resolved
private final GetRequest getRequest; | ||
private final ShardId shardId; | ||
|
||
public Request(GetRequest getRequest, ShardId shardId) { |
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.
GetRequest
is a SingleShardRequest
and can contain a ShardId
, should we check that they are the same?
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.
Indeed if it's the same shardId, then we can re-use the GetRequest
as the request type of the TransportGetFromTranslogAction
.
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.
I did that in an initial version. See this comment. The code in SingleShardRequest
is a bit old school. It keeps an internalShardId
which is mutable and is only used internally. Essentially to reuse it, I'd have to make some internal mutable state of SingleShardRequest
public which is not really worth it I think.
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.
Thanks for pointing to the comment. I do agree SingleShardRequest
did not aged well.
If I understand the code correctly, the internal shard id of the GetRequest is resolved when the request is executed through the TransportGetAction/TransportSingleShardAction, and TransportGetAction will be modified for realtime gets on stateless to use the new TransportGetFromTranslogAction
and the resolved shard id will be passed over the the TransportGetFromTranslogAction.Request.
So we should be fine.
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Outdated
Show resolved
Hide resolved
segmentGeneration = in.readZLong(); | ||
if (in.readBoolean()) { | ||
getResult = new GetResult(in); | ||
} |
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.
Should we assert that segmentGeneration > -1L
when getResult
is null?
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.
null and -1 is a valid state. I have mention that in the comment above segmentGeneration()
, when we don't find anything and there hasn't been any unsafe->safe switches.
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Show resolved
Hide resolved
assertThat(response.getResult().isExists(), equalTo(true)); | ||
assertThat(response.segmentGeneration(), equalTo(-1L)); | ||
// After a refresh we should not be able to get from translog | ||
client().admin().indices().refresh(new RefreshRequest("test")).get(); |
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.
nit: refresh("test")
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.
Nice! Just some minor stuff I believe
server/src/internalClusterTest/java/org/elasticsearch/get/GetFromTranslogActionIT.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Show resolved
Hide resolved
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Outdated
Show resolved
Hide resolved
private final GetRequest getRequest; | ||
private final ShardId shardId; | ||
|
||
public Request(GetRequest getRequest, ShardId shardId) { |
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.
Indeed if it's the same shardId, then we can re-use the GetRequest
as the request type of the TransportGetFromTranslogAction
.
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Outdated
Show resolved
Hide resolved
public void writeTo(StreamOutput out) throws IOException { | ||
out.writeZLong(segmentGeneration); | ||
if (getResult == null) { | ||
out.writeBoolean(false); |
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.
Do we really need to write a boolean? If segmentGeneration != -1, then the result is null and you simply do not need to write anything else.
client().prepareIndex("test").setId("1").setSource("field1", "value1").setRefreshPolicy(RefreshPolicy.NONE).get(); | ||
response = getFromTranslog(indexOrAlias(), "1"); | ||
assertNotNull(response.getResult()); | ||
assertThat(response.getResult().isExists(), equalTo(true)); |
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.
Shouldn't we also assert the real getResult's value? That e.g. it's equal to a document with field1&value1? Similar comment for the similar points below.
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.
I'm not sure why that would matter for this case.
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.
I think it is worth verifying that we are getting the right version of the document from the translog
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.
done
server/src/internalClusterTest/java/org/elasticsearch/get/GetFromTranslogActionIT.java
Show resolved
Hide resolved
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.
Thanks for the reviews. It's ready now again.
Engine engine = indexShard.getEngineOrNull(); | ||
if (engine == null) { | ||
listener.onFailure(new AlreadyClosedException("engine closed")); | ||
return; | ||
} |
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.
You're right, that's not needed there. Slightly outdated code! I've moved it to when result is null.
private final GetRequest getRequest; | ||
private final ShardId shardId; | ||
|
||
public Request(GetRequest getRequest, ShardId shardId) { |
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.
I did that in an initial version. See this comment. The code in SingleShardRequest
is a bit old school. It keeps an internalShardId
which is mutable and is only used internally. Essentially to reuse it, I'd have to make some internal mutable state of SingleShardRequest
public which is not really worth it I think.
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Show resolved
Hide resolved
segmentGeneration = in.readZLong(); | ||
if (in.readBoolean()) { | ||
getResult = new GetResult(in); | ||
} |
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.
null and -1 is a valid state. I have mention that in the comment above segmentGeneration()
, when we don't find anything and there hasn't been any unsafe->safe switches.
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Outdated
Show resolved
Hide resolved
server/src/internalClusterTest/java/org/elasticsearch/get/GetFromTranslogActionIT.java
Show resolved
Hide resolved
client().prepareIndex("test").setId("1").setSource("field1", "value1").setRefreshPolicy(RefreshPolicy.NONE).get(); | ||
response = getFromTranslog(indexOrAlias(), "1"); | ||
assertNotNull(response.getResult()); | ||
assertThat(response.getResult().isExists(), equalTo(true)); |
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.
I'm not sure why that would matter for this case.
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.
LGTM - I only left minor comments, feel free to address them
client().prepareIndex("test").setId("1").setSource("field1", "value1").setRefreshPolicy(RefreshPolicy.NONE).get(); | ||
response = getFromTranslog(indexOrAlias(), "1"); | ||
assertNotNull(response.getResult()); | ||
assertThat(response.getResult().isExists(), equalTo(true)); |
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.
I think it is worth verifying that we are getting the right version of the document from the translog
assertNotNull(response.getResult()); | ||
assertThat(response.getResult().isExists(), equalTo(true)); | ||
assertThat(response.segmentGeneration(), equalTo(-1L)); | ||
// Get followed by a delete should still return a result |
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.
As a side note and for future tests, I think that comment like this are very helpful to understand test failures and can be backed into the assertion methods themselves, ie this could be:
assertThat("Get followed by a delete should still return a result", response.getResult(), nonNullValue());
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.
Great idea!
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Show resolved
Hide resolved
private final GetRequest getRequest; | ||
private final ShardId shardId; | ||
|
||
public Request(GetRequest getRequest, ShardId shardId) { |
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.
Thanks for pointing to the comment. I do agree SingleShardRequest
did not aged well.
If I understand the code correctly, the internal shard id of the GetRequest is resolved when the request is executed through the TransportGetAction/TransportSingleShardAction, and TransportGetAction will be modified for realtime gets on stateless to use the new TransportGetFromTranslogAction
and the resolved shard id will be passed over the the TransportGetFromTranslogAction.Request.
So we should be fine.
|
||
@Override | ||
public String toString() { | ||
return "GetFromTranslogRequest{" + "getRequest=" + getRequest + ", shardId=" + shardId + "}"; |
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.
Maybe just
return "GetFromTranslogRequest{" + "getRequest=" + getRequest + ", shardId=" + shardId + "}"; | |
return "translog " + getRequest; |
as GetRequest.toString already provides useful information?
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.
doesn't seem to include the shardID though.
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Outdated
Show resolved
Hide resolved
server/src/main/java/org/elasticsearch/action/get/TransportGetFromTranslogAction.java
Outdated
Show resolved
Hide resolved
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.
LGTM2. Feel free to consider the remaining unresolved comments.
…FromTranslogAction.java Co-authored-by: Tanguy Leroux <[email protected]>
…FromTranslogAction.java Co-authored-by: Tanguy Leroux <[email protected]>
…gAction' into ps230509-transportGetFromTranslogAction
…etFromTranslogAction
@elasticmachine run elasticsearch-ci/part-2 |
Failure was #96162 |
@elasticmachine update branch |
@elasticmachine run elasticsearch-ci/part-3 Failure is #95983 |
The multi-get counterpart of #95998. Relates ES-5677
This is a change broken off from the ongoing real-time GET PR (#93976).
It is just an action that can be used to invoke the new
ShardGetService.getFromTranslog
in #95736. It will be used on the search shards as a first step to handle a real-time get.
Relates #93976, ES-5537