use of org.opensearch.search.asynchronous.request.SubmitAsynchronousSearchRequest in project asynchronous-search by opensearch-project.
the class AsynchronousSearchRejectionIT method testSimulatedSearchRejectionLoad.
@TestLogging(value = "_root:DEBUG", reason = "flaky")
public void testSimulatedSearchRejectionLoad() throws Throwable {
for (int i = 0; i < 10; i++) {
client().prepareIndex("test").setId(Integer.toString(i)).setSource("field", "1").get();
}
AtomicInteger numRejections = new AtomicInteger();
AtomicInteger numRnf = new AtomicInteger();
AtomicInteger numTimeouts = new AtomicInteger();
AtomicInteger numFailures = new AtomicInteger();
int numberOfAsyncOps = randomIntBetween(100, 200);
final CountDownLatch latch = new CountDownLatch(numberOfAsyncOps * 2);
final CopyOnWriteArrayList<Object> responses = new CopyOnWriteArrayList<>();
for (int i = 0; i < numberOfAsyncOps; i++) {
SearchRequest request = client().prepareSearch("test").setSearchType(SearchType.QUERY_THEN_FETCH).setQuery(QueryBuilders.matchQuery("field", "1")).request();
SubmitAsynchronousSearchRequest submitAsynchronousSearchRequest = new SubmitAsynchronousSearchRequest(request);
submitAsynchronousSearchRequest.waitForCompletionTimeout(TimeValue.timeValueMinutes(1));
boolean keepOnCompletion = randomBoolean();
submitAsynchronousSearchRequest.keepOnCompletion(keepOnCompletion);
client().execute(SubmitAsynchronousSearchAction.INSTANCE, submitAsynchronousSearchRequest, new LatchedActionListener<>(new ActionListener<AsynchronousSearchResponse>() {
@Override
public void onResponse(AsynchronousSearchResponse asynchronousSearchResponse) {
if (asynchronousSearchResponse.getSearchResponse() != null) {
responses.add(asynchronousSearchResponse.getSearchResponse());
} else if (asynchronousSearchResponse.getError() != null) {
responses.add(asynchronousSearchResponse.getError());
}
if (asynchronousSearchResponse.getId() == null) {
// task cancelled by the time we process final response/error due to during partial merge failure.
// no delete required
latch.countDown();
} else {
DeleteAsynchronousSearchRequest deleteAsynchronousSearchRequest = new DeleteAsynchronousSearchRequest(asynchronousSearchResponse.getId());
client().execute(DeleteAsynchronousSearchAction.INSTANCE, deleteAsynchronousSearchRequest, new LatchedActionListener<>(new ActionListener<AcknowledgedResponse>() {
@Override
public void onResponse(AcknowledgedResponse acknowledgedResponse) {
assertTrue(acknowledgedResponse.isAcknowledged());
}
@Override
public void onFailure(Exception e) {
Throwable cause = ExceptionsHelper.unwrapCause(e);
if (cause instanceof OpenSearchRejectedExecutionException) {
numRejections.incrementAndGet();
} else if (cause instanceof OpenSearchTimeoutException) {
numTimeouts.incrementAndGet();
} else if (cause instanceof ResourceNotFoundException) {
// deletion is in race with task cancellation due to partial merge failure
numRnf.getAndIncrement();
} else {
numFailures.incrementAndGet();
}
}
}, latch));
}
}
@Override
public void onFailure(Exception e) {
responses.add(e);
assertThat(e.getMessage(), startsWith("Trying to create too many concurrent searches"));
latch.countDown();
}
}, latch));
}
latch.await();
// validate all responses
for (Object response : responses) {
if (response instanceof SearchResponse) {
SearchResponse searchResponse = (SearchResponse) response;
for (ShardSearchFailure failure : searchResponse.getShardFailures()) {
assertTrue("got unexpected reason..." + failure.reason(), failure.reason().toLowerCase(Locale.ENGLISH).contains("rejected"));
}
} else {
Exception t = (Exception) response;
Throwable unwrap = ExceptionsHelper.unwrapCause(t);
if (unwrap instanceof SearchPhaseExecutionException) {
SearchPhaseExecutionException e = (SearchPhaseExecutionException) unwrap;
for (ShardSearchFailure failure : e.shardFailures()) {
assertTrue("got unexpected reason..." + failure.reason(), // task cancellation can occur due to partial merge failures
failure.reason().toLowerCase(Locale.ENGLISH).contains("cancelled") || failure.reason().toLowerCase(Locale.ENGLISH).contains("rejected"));
}
// we have have null responses if submit completes before search starts
} else if (unwrap instanceof OpenSearchRejectedExecutionException == false) {
throw new AssertionError("unexpected failure + ", (Throwable) response);
}
}
}
assertThat(responses.size(), equalTo(numberOfAsyncOps));
assertThat(numFailures.get(), equalTo(0));
}
use of org.opensearch.search.asynchronous.request.SubmitAsynchronousSearchRequest in project asynchronous-search by opensearch-project.
the class AsynchronousSearchStatsIT method testStatsAcrossNodes.
@TestLogging(value = "_root:DEBUG", reason = "flaky")
public void testStatsAcrossNodes() throws InterruptedException, ExecutionException {
TestThreadPool threadPool = null;
try {
threadPool = new TestThreadPool(AsynchronousSearchStatsIT.class.getName());
String index = "idx";
createIndex(index);
indexRandom(super.ignoreExternalCluster(), client().prepareIndex(index).setId("1").setSource("field1", "the quick brown fox jumps"), client().prepareIndex(index).setId("2").setSource("field1", "quick brown"), client().prepareIndex(index).setId("3").setSource("field1", "quick"));
List<DiscoveryNode> dataNodes = new LinkedList<>();
clusterService().state().nodes().getDataNodes().iterator().forEachRemaining(node -> {
dataNodes.add(node.value);
});
assertFalse(dataNodes.isEmpty());
int numThreads = 20;
List<Runnable> threads = new ArrayList<>();
AtomicLong expectedNumSuccesses = new AtomicLong();
AtomicLong expectedNumFailures = new AtomicLong();
AtomicLong expectedNumPersisted = new AtomicLong();
CountDownLatch latch = new CountDownLatch(numThreads);
for (int i = 0; i < numThreads; i++) {
threads.add(() -> {
try {
boolean success = randomBoolean();
boolean keepOnCompletion = randomBoolean();
if (keepOnCompletion) {
expectedNumPersisted.getAndIncrement();
}
SubmitAsynchronousSearchRequest submitAsynchronousSearchRequest;
if (success) {
expectedNumSuccesses.getAndIncrement();
submitAsynchronousSearchRequest = new SubmitAsynchronousSearchRequest(new SearchRequest(index));
submitAsynchronousSearchRequest.waitForCompletionTimeout(TimeValue.timeValueSeconds(2));
submitAsynchronousSearchRequest.keepOnCompletion(keepOnCompletion);
} else {
expectedNumFailures.getAndIncrement();
submitAsynchronousSearchRequest = new SubmitAsynchronousSearchRequest(new SearchRequest("non_existent_index"));
submitAsynchronousSearchRequest.keepOnCompletion(keepOnCompletion);
}
AsynchronousSearchResponse asResponse = executeSubmitAsynchronousSearch(client(dataNodes.get(randomInt(1)).getName()), submitAsynchronousSearchRequest);
if (keepOnCompletion) {
TestClientUtils.assertResponsePersistence(client(), asResponse.getId());
}
} catch (Exception e) {
fail(e.getMessage());
} finally {
latch.countDown();
}
});
}
TestThreadPool finalThreadPool = threadPool;
threads.forEach(t -> finalThreadPool.generic().execute(t));
latch.await();
AsynchronousSearchStatsResponse statsResponse = client().execute(AsynchronousSearchStatsAction.INSTANCE, new AsynchronousSearchStatsRequest()).get();
AtomicLong actualNumSuccesses = new AtomicLong();
AtomicLong actualNumFailures = new AtomicLong();
AtomicLong actualNumPersisted = new AtomicLong();
for (AsynchronousSearchStats node : statsResponse.getNodes()) {
AsynchronousSearchCountStats asCountStats = node.getAsynchronousSearchCountStats();
assertEquals(asCountStats.getRunningCount(), 0);
assertThat(expectedNumSuccesses.get(), greaterThanOrEqualTo(asCountStats.getCompletedCount()));
actualNumSuccesses.getAndAdd(asCountStats.getCompletedCount());
assertThat(expectedNumFailures.get(), greaterThanOrEqualTo(asCountStats.getFailedCount()));
actualNumFailures.getAndAdd(asCountStats.getFailedCount());
assertThat(expectedNumPersisted.get(), greaterThanOrEqualTo(asCountStats.getPersistedCount()));
actualNumPersisted.getAndAdd(asCountStats.getPersistedCount());
}
assertEquals(expectedNumPersisted.get(), actualNumPersisted.get());
assertEquals(expectedNumFailures.get(), actualNumFailures.get());
assertEquals(expectedNumSuccesses.get(), actualNumSuccesses.get());
waitForAsyncSearchTasksToComplete();
} finally {
ThreadPool.terminate(threadPool, 10, TimeUnit.SECONDS);
}
}
use of org.opensearch.search.asynchronous.request.SubmitAsynchronousSearchRequest in project asynchronous-search by opensearch-project.
the class AsynchronousSearchStatsIT method testNodewiseStats.
public void testNodewiseStats() throws InterruptedException {
String index = "idx";
createIndex(index);
indexRandom(super.ignoreExternalCluster(), client().prepareIndex(index).setId("1").setSource("field1", "the quick brown fox jumps"), client().prepareIndex(index).setId("2").setSource("field1", "quick brown"), client().prepareIndex(index).setId("3").setSource("field1", "quick"));
SubmitAsynchronousSearchRequest submitAsynchronousSearchRequest = new SubmitAsynchronousSearchRequest(new SearchRequest(index));
submitAsynchronousSearchRequest.waitForCompletionTimeout(TimeValue.timeValueSeconds(2));
submitAsynchronousSearchRequest.keepOnCompletion(true);
List<DiscoveryNode> dataNodes = new LinkedList<>();
clusterService().state().nodes().getDataNodes().iterator().forEachRemaining(node -> {
dataNodes.add(node.value);
});
assertFalse(dataNodes.isEmpty());
DiscoveryNode randomDataNode = dataNodes.get(randomInt(dataNodes.size() - 1));
try {
AsynchronousSearchResponse asResponse = executeSubmitAsynchronousSearch(client(randomDataNode.getName()), submitAsynchronousSearchRequest);
assertNotNull(asResponse.getSearchResponse());
TestClientUtils.assertResponsePersistence(client(), asResponse.getId());
AsynchronousSearchStatsResponse statsResponse = client().execute(AsynchronousSearchStatsAction.INSTANCE, new AsynchronousSearchStatsRequest()).get();
String responseAsString = statsResponse.toString();
for (DiscoveryNode dataNode : dataNodes) {
assertThat(responseAsString, containsString(dataNode.getId()));
}
statsResponse.getNodes().forEach(nodeStats -> {
AsynchronousSearchCountStats asCountStats = nodeStats.getAsynchronousSearchCountStats();
if (nodeStats.getNode().equals(randomDataNode)) {
assertEquals(1, asCountStats.getPersistedCount());
assertEquals(1, asCountStats.getCompletedCount());
assertEquals(1, asCountStats.getSubmittedCount());
assertEquals(1, asCountStats.getInitializedCount());
assertEquals(0, asCountStats.getFailedCount());
assertEquals(0, asCountStats.getRunningCount());
assertEquals(0, asCountStats.getCancelledCount());
} else {
assertEquals(0, asCountStats.getPersistedCount());
assertEquals(0, asCountStats.getCompletedCount());
assertEquals(0, asCountStats.getFailedCount());
assertEquals(0, asCountStats.getRunningCount());
}
});
} catch (Exception e) {
fail(e.getMessage());
}
}
use of org.opensearch.search.asynchronous.request.SubmitAsynchronousSearchRequest in project asynchronous-search by opensearch-project.
the class AsynchronousSearchStatsIT method testRunningAsynchronousSearchCountStat.
public void testRunningAsynchronousSearchCountStat() throws InterruptedException, ExecutionException {
String index = "idx";
createIndex(index);
indexRandom(super.ignoreExternalCluster(), client().prepareIndex(index).setId("1").setSource("field1", "the quick brown fox jumps"), client().prepareIndex(index).setId("2").setSource("field1", "quick brown"), client().prepareIndex(index).setId("3").setSource("field1", "quick"));
List<ScriptedBlockPlugin> plugins = initBlockFactory();
SearchRequest searchRequest = client().prepareSearch(index).setQuery(scriptQuery(new Script(ScriptType.INLINE, "mockscript", SCRIPT_NAME, Collections.emptyMap()))).request();
SubmitAsynchronousSearchRequest submitAsynchronousSearchRequest = new SubmitAsynchronousSearchRequest(searchRequest);
submitAsynchronousSearchRequest.keepOnCompletion(true);
AsynchronousSearchResponse asResponse = executeSubmitAsynchronousSearch(client(), submitAsynchronousSearchRequest);
AsynchronousSearchStatsResponse statsResponse = client().execute(AsynchronousSearchStatsAction.INSTANCE, new AsynchronousSearchStatsRequest()).get();
long runningSearchCount = 0;
for (AsynchronousSearchStats node : statsResponse.getNodes()) {
runningSearchCount += node.getAsynchronousSearchCountStats().getRunningCount();
assertEquals(node.getAsynchronousSearchCountStats().getCompletedCount(), 0L);
assertEquals(node.getAsynchronousSearchCountStats().getFailedCount(), 0L);
assertEquals(node.getAsynchronousSearchCountStats().getPersistedCount(), 0L);
}
assertEquals(runningSearchCount, 1L);
disableBlocks(plugins);
TestClientUtils.assertResponsePersistence(client(), asResponse.getId());
statsResponse = client().execute(AsynchronousSearchStatsAction.INSTANCE, new AsynchronousSearchStatsRequest()).get();
long persistedCount = 0;
long completedCount = 0;
for (AsynchronousSearchStats node : statsResponse.getNodes()) {
persistedCount += node.getAsynchronousSearchCountStats().getPersistedCount();
completedCount += node.getAsynchronousSearchCountStats().getCompletedCount();
assertEquals(node.getAsynchronousSearchCountStats().getRunningCount(), 0L);
assertEquals(node.getAsynchronousSearchCountStats().getFailedCount(), 0L);
}
assertEquals(runningSearchCount, 1L);
}
use of org.opensearch.search.asynchronous.request.SubmitAsynchronousSearchRequest in project asynchronous-search by opensearch-project.
the class AsyncSearchBackwardsCompatibilityIT method testSubmitWithRetainedResponse.
public void testSubmitWithRetainedResponse(boolean shouldUseLegacyApi) throws IOException {
SearchRequest searchRequest = new SearchRequest("test");
searchRequest.source(new SearchSourceBuilder());
SubmitAsynchronousSearchRequest submitAsynchronousSearchRequest = new SubmitAsynchronousSearchRequest(searchRequest);
submitAsynchronousSearchRequest.keepOnCompletion(true);
submitAsynchronousSearchRequest.waitForCompletionTimeout(TimeValue.timeValueMillis(randomLongBetween(1, 500)));
AsynchronousSearchResponse submitResponse = executeSubmitAsynchronousSearch(submitAsynchronousSearchRequest, shouldUseLegacyApi);
List<AsynchronousSearchState> legalStates = Arrays.asList(AsynchronousSearchState.RUNNING, AsynchronousSearchState.SUCCEEDED, AsynchronousSearchState.PERSIST_SUCCEEDED, AsynchronousSearchState.PERSISTING, AsynchronousSearchState.CLOSED, AsynchronousSearchState.STORE_RESIDENT);
assertNotNull(submitResponse.getId());
assertTrue(submitResponse.getState().name(), legalStates.contains(submitResponse.getState()));
GetAsynchronousSearchRequest getAsynchronousSearchRequest = new GetAsynchronousSearchRequest(submitResponse.getId());
AsynchronousSearchResponse getResponse;
do {
getResponse = getAssertedAsynchronousSearchResponse(submitResponse, getAsynchronousSearchRequest, shouldUseLegacyApi);
if (getResponse.getState() == AsynchronousSearchState.RUNNING && getResponse.getSearchResponse() != null) {
assertEquals(getResponse.getSearchResponse().getHits().getHits().length, 0);
} else {
assertNotNull(getResponse.getSearchResponse());
assertNotEquals(getResponse.getSearchResponse().getTook(), -1L);
}
} while (AsynchronousSearchState.STORE_RESIDENT.equals(getResponse.getState()) == false);
getResponse = getAssertedAsynchronousSearchResponse(submitResponse, getAsynchronousSearchRequest, shouldUseLegacyApi);
assertNotNull(getResponse.getSearchResponse());
assertEquals(AsynchronousSearchState.STORE_RESIDENT, getResponse.getState());
assertHitCount(getResponse.getSearchResponse(), 5);
executeDeleteAsynchronousSearch(new DeleteAsynchronousSearchRequest(submitResponse.getId()), shouldUseLegacyApi);
}
Aggregations