Search in sources :

Example 1 with TaskGroup

use of org.elasticsearch.action.admin.cluster.node.tasks.list.TaskGroup in project elasticsearch by elastic.

the class TransportTasksActionTests method testRunningTasksCount.

public void testRunningTasksCount() throws Exception {
    setupTestNodes(Settings.EMPTY);
    connectNodes(testNodes);
    CountDownLatch checkLatch = new CountDownLatch(1);
    CountDownLatch responseLatch = new CountDownLatch(1);
    final AtomicReference<NodesResponse> responseReference = new AtomicReference<>();
    Task mainTask = startBlockingTestNodesAction(checkLatch, new ActionListener<NodesResponse>() {

        @Override
        public void onResponse(NodesResponse listTasksResponse) {
            responseReference.set(listTasksResponse);
            responseLatch.countDown();
        }

        @Override
        public void onFailure(Exception e) {
            logger.warn("Couldn't get list of tasks", e);
            responseLatch.countDown();
        }
    });
    // Check task counts using taskManager
    Map<Long, Task> localTasks = testNodes[0].transportService.getTaskManager().getTasks();
    // all node tasks + 1 coordinating task
    assertEquals(2, localTasks.size());
    Task coordinatingTask = localTasks.get(Collections.min(localTasks.keySet()));
    Task subTask = localTasks.get(Collections.max(localTasks.keySet()));
    assertThat(subTask.getAction(), endsWith("[n]"));
    assertThat(coordinatingTask.getAction(), not(endsWith("[n]")));
    for (int i = 1; i < testNodes.length; i++) {
        Map<Long, Task> remoteTasks = testNodes[i].transportService.getTaskManager().getTasks();
        assertEquals(1, remoteTasks.size());
        Task remoteTask = remoteTasks.values().iterator().next();
        assertThat(remoteTask.getAction(), endsWith("[n]"));
    }
    // Check task counts using transport
    int testNodeNum = randomIntBetween(0, testNodes.length - 1);
    TestNode testNode = testNodes[testNodeNum];
    ListTasksRequest listTasksRequest = new ListTasksRequest();
    // pick all test actions
    listTasksRequest.setActions("testAction*");
    logger.info("Listing currently running tasks using node [{}]", testNodeNum);
    ListTasksResponse response = testNode.transportListTasksAction.execute(listTasksRequest).get();
    logger.info("Checking currently running tasks");
    assertEquals(testNodes.length, response.getPerNodeTasks().size());
    // Coordinating node
    assertEquals(2, response.getPerNodeTasks().get(testNodes[0].getNodeId()).size());
    // Other nodes node
    for (int i = 1; i < testNodes.length; i++) {
        assertEquals(1, response.getPerNodeTasks().get(testNodes[i].getNodeId()).size());
    }
    // There should be a single main task when grouped by tasks
    assertEquals(1, response.getTaskGroups().size());
    // And as many child tasks as we have nodes
    assertEquals(testNodes.length, response.getTaskGroups().get(0).getChildTasks().size());
    // Check task counts using transport with filtering
    testNode = testNodes[randomIntBetween(0, testNodes.length - 1)];
    listTasksRequest = new ListTasksRequest();
    // only pick node actions
    listTasksRequest.setActions("testAction[n]");
    response = testNode.transportListTasksAction.execute(listTasksRequest).get();
    assertEquals(testNodes.length, response.getPerNodeTasks().size());
    for (Map.Entry<String, List<TaskInfo>> entry : response.getPerNodeTasks().entrySet()) {
        assertEquals(1, entry.getValue().size());
        assertNull(entry.getValue().get(0).getDescription());
    }
    // Since the main task is not in the list - all tasks should be by themselves
    assertEquals(testNodes.length, response.getTaskGroups().size());
    for (TaskGroup taskGroup : response.getTaskGroups()) {
        assertEquals(0, taskGroup.getChildTasks().size());
    }
    // Check task counts using transport with detailed description
    // same request only with detailed description
    listTasksRequest.setDetailed(true);
    response = testNode.transportListTasksAction.execute(listTasksRequest).get();
    assertEquals(testNodes.length, response.getPerNodeTasks().size());
    for (Map.Entry<String, List<TaskInfo>> entry : response.getPerNodeTasks().entrySet()) {
        assertEquals(1, entry.getValue().size());
        assertEquals("CancellableNodeRequest[Test Request, true]", entry.getValue().get(0).getDescription());
    }
    // Make sure that the main task on coordinating node is the task that was returned to us by execute()
    // only pick the main task
    listTasksRequest.setActions("testAction");
    response = testNode.transportListTasksAction.execute(listTasksRequest).get();
    assertEquals(1, response.getTasks().size());
    assertEquals(mainTask.getId(), response.getTasks().get(0).getId());
    // Release all tasks and wait for response
    checkLatch.countDown();
    assertTrue(responseLatch.await(10, TimeUnit.SECONDS));
    NodesResponse responses = responseReference.get();
    assertEquals(0, responses.failureCount());
    // Make sure that we don't have any lingering tasks
    for (TestNode node : testNodes) {
        assertEquals(0, node.transportService.getTaskManager().getTasks().size());
    }
}
Also used : Task(org.elasticsearch.tasks.Task) AtomicReference(java.util.concurrent.atomic.AtomicReference) Matchers.containsString(org.hamcrest.Matchers.containsString) CountDownLatch(java.util.concurrent.CountDownLatch) ListTasksResponse(org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse) FailedNodeException(org.elasticsearch.action.FailedNodeException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) ListTasksRequest(org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksRequest) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) TaskGroup(org.elasticsearch.action.admin.cluster.node.tasks.list.TaskGroup)

Example 2 with TaskGroup

use of org.elasticsearch.action.admin.cluster.node.tasks.list.TaskGroup in project elasticsearch by elastic.

the class RethrottleTests method testCase.

private void testCase(AbstractBulkByScrollRequestBuilder<?, ?> request, String actionName) throws Exception {
    logger.info("Starting test for [{}] with [{}] slices", actionName, request.request().getSlices());
    /* Add ten documents per slice so most slices will have many documents to process, having to go to multiple batches.
         * we can't rely on all of them doing so, but 
         */
    List<IndexRequestBuilder> docs = new ArrayList<>();
    for (int i = 0; i < request.request().getSlices() * 10; i++) {
        docs.add(client().prepareIndex("test", "test", Integer.toString(i)).setSource("foo", "bar"));
    }
    indexRandom(true, docs);
    // Start a request that will never finish unless we rethrottle it
    // Throttle "forever"
    request.setRequestsPerSecond(.000001f);
    // Make sure we use multiple batches
    request.source().setSize(1);
    ListenableActionFuture<? extends BulkByScrollResponse> responseListener = request.execute();
    TaskGroup taskGroupToRethrottle = findTaskToRethrottle(actionName, request.request().getSlices());
    TaskId taskToRethrottle = taskGroupToRethrottle.getTaskInfo().getTaskId();
    if (request.request().getSlices() == 1) {
        assertThat(taskGroupToRethrottle.getChildTasks(), empty());
    } else {
        // There should be a sane number of child tasks running
        assertThat(taskGroupToRethrottle.getChildTasks(), hasSize(allOf(greaterThanOrEqualTo(1), lessThanOrEqualTo(request.request().getSlices()))));
        // Wait for all of the sub tasks to start (or finish, some might finish early, all that matters is that not all do)
        assertBusy(() -> {
            BulkByScrollTask.Status parent = (BulkByScrollTask.Status) client().admin().cluster().prepareGetTask(taskToRethrottle).get().getTask().getTask().getStatus();
            long finishedSubTasks = parent.getSliceStatuses().stream().filter(s -> s != null).count();
            ListTasksResponse list = client().admin().cluster().prepareListTasks().setParentTaskId(taskToRethrottle).get();
            list.rethrowFailures("subtasks");
            assertThat(finishedSubTasks + list.getTasks().size(), greaterThanOrEqualTo((long) request.request().getSlices()));
            assertThat(list.getTasks().size(), greaterThan(0));
        });
    }
    // Now rethrottle it so it'll finish
    // No throttle or "very fast"
    float newRequestsPerSecond = randomBoolean() ? Float.POSITIVE_INFINITY : between(1, 1000) * 100000;
    ListTasksResponse rethrottleResponse = rethrottle().setTaskId(taskToRethrottle).setRequestsPerSecond(newRequestsPerSecond).get();
    rethrottleResponse.rethrowFailures("Rethrottle");
    assertThat(rethrottleResponse.getTasks(), hasSize(1));
    BulkByScrollTask.Status status = (BulkByScrollTask.Status) rethrottleResponse.getTasks().get(0).getStatus();
    // Now check the resulting requests per second.
    if (request.request().getSlices() == 1) {
        // If there is a single slice it should match perfectly
        assertEquals(newRequestsPerSecond, status.getRequestsPerSecond(), Float.MIN_NORMAL);
    } else {
        /* Check that at least one slice was rethrottled. We won't always rethrottle all of them because they might have completed.
             * With multiple slices these numbers might not add up perfectly, thus the 1.01F. */
        long unfinished = status.getSliceStatuses().stream().filter(slice -> slice != null).filter(slice -> slice.getStatus().getTotal() > slice.getStatus().getSuccessfullyProcessed()).count();
        float maxExpectedSliceRequestsPerSecond = newRequestsPerSecond == Float.POSITIVE_INFINITY ? Float.POSITIVE_INFINITY : (newRequestsPerSecond / unfinished) * 1.01F;
        float minExpectedSliceRequestsPerSecond = newRequestsPerSecond == Float.POSITIVE_INFINITY ? Float.POSITIVE_INFINITY : (newRequestsPerSecond / request.request().getSlices()) * 0.99F;
        boolean oneSliceRethrottled = false;
        float totalRequestsPerSecond = 0;
        for (BulkByScrollTask.StatusOrException statusOrException : status.getSliceStatuses()) {
            if (statusOrException == null) {
                /* The slice can be null here because it was completed but hadn't reported its success back to the task when the
                     * rethrottle request came through. */
                continue;
            }
            assertNull(statusOrException.getException());
            BulkByScrollTask.Status slice = statusOrException.getStatus();
            if (slice.getTotal() > slice.getSuccessfullyProcessed()) {
                // This slice reports as not having completed so it should have been processed.
                assertThat(slice.getRequestsPerSecond(), both(greaterThanOrEqualTo(minExpectedSliceRequestsPerSecond)).and(lessThanOrEqualTo(maxExpectedSliceRequestsPerSecond)));
            }
            if (minExpectedSliceRequestsPerSecond <= slice.getRequestsPerSecond() && slice.getRequestsPerSecond() <= maxExpectedSliceRequestsPerSecond) {
                oneSliceRethrottled = true;
            }
            totalRequestsPerSecond += slice.getRequestsPerSecond();
        }
        assertTrue("At least one slice must be rethrottled", oneSliceRethrottled);
        /* Now assert that the parent request has the total requests per second. This is a much weaker assertion than that the parent
             * actually has the newRequestsPerSecond. For the most part it will. Sometimes it'll be greater because only unfinished requests
             * are rethrottled, the finished ones just keep whatever requests per second they had while they were running. But it might
             * also be less than newRequestsPerSecond because the newRequestsPerSecond is divided among running sub-requests and then the
             * requests are rethrottled. If one request finishes in between the division and the application of the new throttle then it
             * won't be rethrottled, thus only contributing its lower total. */
        assertEquals(totalRequestsPerSecond, status.getRequestsPerSecond(), totalRequestsPerSecond * 0.0001f);
    }
    // Now the response should come back quickly because we've rethrottled the request
    BulkByScrollResponse response = responseListener.get();
    assertThat("Entire request completed in a single batch. This may invalidate the test as throttling is done between batches.", response.getBatches(), greaterThanOrEqualTo(request.request().getSlices()));
}
Also used : BulkByScrollResponse(org.elasticsearch.action.bulk.byscroll.BulkByScrollResponse) Matchers.empty(org.hamcrest.Matchers.empty) Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) Matchers.allOf(org.hamcrest.Matchers.allOf) Matchers.lessThanOrEqualTo(org.hamcrest.Matchers.lessThanOrEqualTo) AbstractBulkByScrollRequestBuilder(org.elasticsearch.action.bulk.byscroll.AbstractBulkByScrollRequestBuilder) ListenableActionFuture(org.elasticsearch.action.ListenableActionFuture) TaskId(org.elasticsearch.tasks.TaskId) ArrayList(java.util.ArrayList) Matchers.both(org.hamcrest.Matchers.both) ListTasksResponse(org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) IndexRequestBuilder(org.elasticsearch.action.index.IndexRequestBuilder) Matchers.lessThan(org.hamcrest.Matchers.lessThan) Matchers.hasSize(org.hamcrest.Matchers.hasSize) Matchers.greaterThan(org.hamcrest.Matchers.greaterThan) TaskGroup(org.elasticsearch.action.admin.cluster.node.tasks.list.TaskGroup) BulkByScrollTask(org.elasticsearch.action.bulk.byscroll.BulkByScrollTask) TaskId(org.elasticsearch.tasks.TaskId) ArrayList(java.util.ArrayList) ListTasksResponse(org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse) BulkByScrollResponse(org.elasticsearch.action.bulk.byscroll.BulkByScrollResponse) IndexRequestBuilder(org.elasticsearch.action.index.IndexRequestBuilder) BulkByScrollTask(org.elasticsearch.action.bulk.byscroll.BulkByScrollTask) TaskGroup(org.elasticsearch.action.admin.cluster.node.tasks.list.TaskGroup)

Example 3 with TaskGroup

use of org.elasticsearch.action.admin.cluster.node.tasks.list.TaskGroup in project elasticsearch by elastic.

the class RethrottleTests method findTaskToRethrottle.

private TaskGroup findTaskToRethrottle(String actionName, int sliceCount) {
    long start = System.nanoTime();
    do {
        ListTasksResponse tasks = client().admin().cluster().prepareListTasks().setActions(actionName).setDetailed(true).get();
        tasks.rethrowFailures("Finding tasks to rethrottle");
        assertThat(tasks.getTaskGroups(), hasSize(lessThan(2)));
        if (0 == tasks.getTaskGroups().size()) {
            continue;
        }
        TaskGroup taskGroup = tasks.getTaskGroups().get(0);
        if (sliceCount != 1 && taskGroup.getChildTasks().size() == 0) {
            // If there are child tasks wait for at least one to start
            continue;
        }
        return taskGroup;
    } while (System.nanoTime() - start < TimeUnit.SECONDS.toNanos(10));
    throw new AssertionError("Couldn't find tasks to rethrottle. Here are the running tasks " + client().admin().cluster().prepareListTasks().get());
}
Also used : ListTasksResponse(org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse) TaskGroup(org.elasticsearch.action.admin.cluster.node.tasks.list.TaskGroup)

Example 4 with TaskGroup

use of org.elasticsearch.action.admin.cluster.node.tasks.list.TaskGroup in project elasticsearch by elastic.

the class RestTasksAction method buildGroups.

private void buildGroups(Table table, boolean fullId, boolean detailed, List<TaskGroup> taskGroups) {
    DiscoveryNodes discoveryNodes = nodesInCluster.get();
    List<TaskGroup> sortedGroups = new ArrayList<>(taskGroups);
    sortedGroups.sort((o1, o2) -> Long.compare(o1.getTaskInfo().getStartTime(), o2.getTaskInfo().getStartTime()));
    for (TaskGroup taskGroup : sortedGroups) {
        buildRow(table, fullId, detailed, discoveryNodes, taskGroup.getTaskInfo());
        buildGroups(table, fullId, detailed, taskGroup.getChildTasks());
    }
}
Also used : ArrayList(java.util.ArrayList) TaskGroup(org.elasticsearch.action.admin.cluster.node.tasks.list.TaskGroup) DiscoveryNodes(org.elasticsearch.cluster.node.DiscoveryNodes)

Aggregations

TaskGroup (org.elasticsearch.action.admin.cluster.node.tasks.list.TaskGroup)4 ArrayList (java.util.ArrayList)3 ListTasksResponse (org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksResponse)3 List (java.util.List)2 IOException (java.io.IOException)1 Map (java.util.Map)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 ExecutionException (java.util.concurrent.ExecutionException)1 TimeUnit (java.util.concurrent.TimeUnit)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 FailedNodeException (org.elasticsearch.action.FailedNodeException)1 ListenableActionFuture (org.elasticsearch.action.ListenableActionFuture)1 ListTasksRequest (org.elasticsearch.action.admin.cluster.node.tasks.list.ListTasksRequest)1 AbstractBulkByScrollRequestBuilder (org.elasticsearch.action.bulk.byscroll.AbstractBulkByScrollRequestBuilder)1 BulkByScrollResponse (org.elasticsearch.action.bulk.byscroll.BulkByScrollResponse)1 BulkByScrollTask (org.elasticsearch.action.bulk.byscroll.BulkByScrollTask)1 IndexRequestBuilder (org.elasticsearch.action.index.IndexRequestBuilder)1 DiscoveryNodes (org.elasticsearch.cluster.node.DiscoveryNodes)1 Task (org.elasticsearch.tasks.Task)1 TaskId (org.elasticsearch.tasks.TaskId)1