Search in sources :

Example 11 with BulkByScrollResponse

use of org.elasticsearch.action.bulk.byscroll.BulkByScrollResponse in project elasticsearch by elastic.

the class CancelTests method testCancel.

/**
     * Executes the cancellation test
     */
private void testCancel(String action, AbstractBulkByScrollRequestBuilder<?, ?> builder, CancelAssertion assertion, Matcher<String> taskDescriptionMatcher) throws Exception {
    createIndex(INDEX);
    // Total number of documents created for this test (~10 per primary shard per shard)
    int numDocs = getNumShards(INDEX).numPrimaries * 10 * builder.request().getSlices();
    ALLOWED_OPERATIONS.release(numDocs);
    indexRandom(true, false, true, IntStream.range(0, numDocs).mapToObj(i -> client().prepareIndex(INDEX, TYPE, String.valueOf(i)).setSource("n", i)).collect(Collectors.toList()));
    // Checks that the all documents have been indexed and correctly counted
    assertHitCount(client().prepareSearch(INDEX).setSize(0).get(), numDocs);
    assertThat(ALLOWED_OPERATIONS.drainPermits(), equalTo(0));
    // Scroll by 1 so that cancellation is easier to control
    builder.source().setSize(1);
    /* Allow a random number of the documents less the number of workers to be modified by the reindex action. That way at least one
         * worker is blocked. */
    int numModifiedDocs = randomIntBetween(builder.request().getSlices() * 2, numDocs);
    ALLOWED_OPERATIONS.release(numModifiedDocs - builder.request().getSlices());
    // Now execute the reindex action...
    ListenableActionFuture<? extends BulkByScrollResponse> future = builder.execute();
    /* ... and waits for the indexing operation listeners to block. It is important to realize that some of the workers might have
         * exhausted their slice while others might have quite a bit left to work on. We can't control that. */
    awaitBusy(() -> ALLOWED_OPERATIONS.hasQueuedThreads() && ALLOWED_OPERATIONS.availablePermits() == 0);
    // Status should show the task running
    TaskInfo mainTask = findTaskToCancel(action, builder.request().getSlices());
    BulkByScrollTask.Status status = (BulkByScrollTask.Status) mainTask.getStatus();
    assertNull(status.getReasonCancelled());
    // Description shouldn't be empty
    assertThat(mainTask.getDescription(), taskDescriptionMatcher);
    // Cancel the request while the reindex action is blocked by the indexing operation listeners.
    // This will prevent further requests from being sent.
    ListTasksResponse cancelTasksResponse = client().admin().cluster().prepareCancelTasks().setTaskId(mainTask.getTaskId()).get();
    cancelTasksResponse.rethrowFailures("Cancel");
    assertThat(cancelTasksResponse.getTasks(), hasSize(1));
    // The status should now show canceled. The request will still be in the list because it is (or its children are) still blocked.
    mainTask = client().admin().cluster().prepareGetTask(mainTask.getTaskId()).get().getTask().getTask();
    status = (BulkByScrollTask.Status) mainTask.getStatus();
    assertEquals(CancelTasksRequest.DEFAULT_REASON, status.getReasonCancelled());
    if (builder.request().getSlices() > 1) {
        boolean foundCancelled = false;
        ListTasksResponse sliceList = client().admin().cluster().prepareListTasks().setParentTaskId(mainTask.getTaskId()).setDetailed(true).get();
        sliceList.rethrowFailures("Fetch slice tasks");
        for (TaskInfo slice : sliceList.getTasks()) {
            BulkByScrollTask.Status sliceStatus = (BulkByScrollTask.Status) slice.getStatus();
            if (sliceStatus.getReasonCancelled() == null)
                continue;
            assertEquals(CancelTasksRequest.DEFAULT_REASON, sliceStatus.getReasonCancelled());
            foundCancelled = true;
        }
        assertTrue("Didn't find at least one sub task that was cancelled", foundCancelled);
    }
    // Unblock the last operations
    ALLOWED_OPERATIONS.release(builder.request().getSlices());
    // Checks that no more operations are executed
    assertBusy(() -> {
        if (builder.request().getSlices() == 1) {
            /* We can only be sure that we've drained all the permits if we only use a single worker. Otherwise some worker may have
                 * exhausted all of its documents before we blocked. */
            assertEquals(0, ALLOWED_OPERATIONS.availablePermits());
        }
        assertEquals(0, ALLOWED_OPERATIONS.getQueueLength());
    });
    // And check the status of the response
    BulkByScrollResponse response = future.get();
    assertThat(response.getReasonCancelled(), equalTo("by user request"));
    assertThat(response.getBulkFailures(), emptyIterable());
    assertThat(response.getSearchFailures(), emptyIterable());
    if (builder.request().getSlices() >= 1) {
        // If we have more than one worker we might not have made all the modifications
        numModifiedDocs -= ALLOWED_OPERATIONS.availablePermits();
    }
    flushAndRefresh(INDEX);
    assertion.assertThat(response, numDocs, numModifiedDocs);
}
Also used : TaskInfo(org.elasticsearch.tasks.TaskInfo) BulkByScrollTask(org.elasticsearch.action.bulk.byscroll.BulkByScrollTask) ListTasksResponse(org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse) BulkByScrollResponse(org.elasticsearch.action.bulk.byscroll.BulkByScrollResponse)

Aggregations

BulkByScrollResponse (org.elasticsearch.action.bulk.byscroll.BulkByScrollResponse)11 ArrayList (java.util.ArrayList)6 BulkByScrollTask (org.elasticsearch.action.bulk.byscroll.BulkByScrollTask)5 IndexRequestBuilder (org.elasticsearch.action.index.IndexRequestBuilder)4 ListTasksResponse (org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse)3 Failure (org.elasticsearch.action.bulk.BulkItemResponse.Failure)2 ParentBulkByScrollTask (org.elasticsearch.action.bulk.byscroll.ParentBulkByScrollTask)2 TaskId (org.elasticsearch.tasks.TaskId)2 TaskInfo (org.elasticsearch.tasks.TaskInfo)2 List (java.util.List)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 CyclicBarrier (java.util.concurrent.CyclicBarrier)1 TimeUnit (java.util.concurrent.TimeUnit)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 AtomicLong (java.util.concurrent.atomic.AtomicLong)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 TestUtil.randomSimpleString (org.apache.lucene.util.TestUtil.randomSimpleString)1 ActionListener (org.elasticsearch.action.ActionListener)1 ListenableActionFuture (org.elasticsearch.action.ListenableActionFuture)1 TaskGroup (org.elasticsearch.action.admin.cluster.node.tasks.list.TaskGroup)1