-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Fix SearchErrorTraceIT and friends to work with batched query execution #127150
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
base: main
Are you sure you want to change the base?
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 |
---|---|---|
|
@@ -11,12 +11,14 @@ | |
|
||
import org.apache.logging.log4j.Level; | ||
import org.elasticsearch.ExceptionsHelper; | ||
import org.elasticsearch.action.search.SearchQueryThenFetchAsyncAction; | ||
import org.elasticsearch.index.query.QueryShardException; | ||
import org.elasticsearch.test.ESIntegTestCase; | ||
import org.elasticsearch.test.InternalTestCluster; | ||
import org.elasticsearch.test.MockLog; | ||
import org.elasticsearch.test.transport.MockTransportService; | ||
import org.elasticsearch.transport.TransportMessageListener; | ||
import org.elasticsearch.transport.TransportResponse; | ||
import org.elasticsearch.transport.TransportService; | ||
|
||
import java.util.Arrays; | ||
|
@@ -38,20 +40,36 @@ public enum ErrorTraceHelper { | |
|
||
public static BooleanSupplier setupErrorTraceListener(InternalTestCluster internalCluster) { | ||
final AtomicBoolean transportMessageHasStackTrace = new AtomicBoolean(false); | ||
internalCluster.getDataNodeInstances(TransportService.class) | ||
.forEach(ts -> asInstanceOf(MockTransportService.class, ts).addMessageListener(new TransportMessageListener() { | ||
internalCluster.getDataNodeInstances(TransportService.class).forEach(ts -> { | ||
var mockTs = asInstanceOf(MockTransportService.class, ts); | ||
mockTs.addMessageListener(new TransportMessageListener() { | ||
@Override | ||
public void onResponseSent(long requestId, String action, Exception error) { | ||
TransportMessageListener.super.onResponseSent(requestId, action, error); | ||
if (action.startsWith("indices:data/read/search")) { | ||
Optional<Throwable> throwable = ExceptionsHelper.unwrapCausesAndSuppressed( | ||
error, | ||
t -> t.getStackTrace().length > 0 | ||
); | ||
transportMessageHasStackTrace.set(throwable.isPresent()); | ||
checkStacktraceStateAndRemove(error, mockTs); | ||
} | ||
} | ||
})); | ||
|
||
@Override | ||
public void onBeforeResponseSent(long requestId, String action, TransportResponse response) { | ||
if (SearchQueryThenFetchAsyncAction.NODE_SEARCH_ACTION_NAME.equals(action)) { | ||
var r = asInstanceOf(SearchQueryThenFetchAsyncAction.NodeQueryResponse.class, response); | ||
for (Object result : r.getResults()) { | ||
if (result instanceof Exception error) { | ||
checkStacktraceStateAndRemove(error, mockTs); | ||
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. Is looping + setting the 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. It's not great, I sort of tried to point this out via the fact that we only see a single request per thread in the op too. 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. Shouldn't this do something like: capture the existence of a stack trace for ALL exception results, and:
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. Right that would work but also make this even harder to follow? If we want to fix this my vote would be to invest 5 more minutes here and just assert inline so that we can pass the expectation for everything to the listener at the beginning of each test? :) Otherwise if we go for the 3 outcome logic, we'll have some inline assertions and some "at the end of the test" assertions mixed, that's just needlessly complex? 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. Ah I see what you mean now - throw out |
||
} | ||
} | ||
} | ||
} | ||
|
||
private void checkStacktraceStateAndRemove(Exception error, MockTransportService mockTs) { | ||
Optional<Throwable> throwable = ExceptionsHelper.unwrapCausesAndSuppressed(error, t -> t.getStackTrace().length > 0); | ||
transportMessageHasStackTrace.set(throwable.isPresent()); | ||
mockTs.removeMessageListener(this); | ||
} | ||
}); | ||
}); | ||
return transportMessageHasStackTrace::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.
@DaveCTurner wdyt? this should be ok right? In prod the overhead is negligible I think.