Search in sources :

Example 1 with CancellableTask

use of org.opensearch.tasks.CancellableTask in project OpenSearch by opensearch-project.

the class TimeoutTaskCancellationUtility method wrapWithCancellationListener.

/**
 * Wraps a listener with a timeout listener {@link TimeoutRunnableListener} to schedule the task cancellation for provided tasks on
 * generic thread pool
 * @param client - {@link NodeClient}
 * @param taskToCancel - task to schedule cancellation for
 * @param clusterSettings - {@link ClusterSettings}
 * @param listener - original listener associated with the task
 * @return wrapped listener
 */
public static <Response> ActionListener<Response> wrapWithCancellationListener(NodeClient client, CancellableTask taskToCancel, ClusterSettings clusterSettings, ActionListener<Response> listener) {
    final TimeValue globalTimeout = clusterSettings.get(SEARCH_CANCEL_AFTER_TIME_INTERVAL_SETTING);
    final TimeValue timeoutInterval = (taskToCancel.getCancellationTimeout() == null) ? globalTimeout : taskToCancel.getCancellationTimeout();
    // Note: -1 (or no timeout) will help to turn off cancellation. The combinations will be request level set at -1 or request level
    // set to null and cluster level set to -1.
    ActionListener<Response> listenerToReturn = listener;
    if (timeoutInterval.equals(SearchService.NO_TIMEOUT)) {
        return listenerToReturn;
    }
    try {
        final TimeoutRunnableListener<Response> wrappedListener = new TimeoutRunnableListener<>(timeoutInterval, listener, () -> {
            final CancelTasksRequest cancelTasksRequest = new CancelTasksRequest();
            cancelTasksRequest.setTaskId(new TaskId(client.getLocalNodeId(), taskToCancel.getId()));
            cancelTasksRequest.setReason("Cancellation timeout of " + timeoutInterval + " is expired");
            // force the origin to execute the cancellation as a system user
            new OriginSettingClient(client, TASKS_ORIGIN).admin().cluster().cancelTasks(cancelTasksRequest, ActionListener.wrap(r -> logger.debug("Scheduled cancel task with timeout: {} for original task: {} is successfully completed", timeoutInterval, cancelTasksRequest.getTaskId()), e -> logger.error(new ParameterizedMessage("Scheduled cancel task with timeout: {} for original task: {} is failed", timeoutInterval, cancelTasksRequest.getTaskId()), e)));
        });
        wrappedListener.cancellable = client.threadPool().schedule(wrappedListener, timeoutInterval, ThreadPool.Names.GENERIC);
        listenerToReturn = wrappedListener;
    } catch (Exception ex) {
        // if there is any exception in scheduling the cancellation task then continue without it
        logger.warn("Failed to schedule the cancellation task for original task: {}, will continue without it", taskToCancel.getId());
    }
    return listenerToReturn;
}
Also used : TimeValue(org.opensearch.common.unit.TimeValue) NodeClient(org.opensearch.client.node.NodeClient) ThreadPool(org.opensearch.threadpool.ThreadPool) TaskId(org.opensearch.tasks.TaskId) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) TimeUnit(java.util.concurrent.TimeUnit) Logger(org.apache.logging.log4j.Logger) CancelTasksRequest(org.opensearch.action.admin.cluster.node.tasks.cancel.CancelTasksRequest) SEARCH_CANCEL_AFTER_TIME_INTERVAL_SETTING(org.opensearch.action.search.TransportSearchAction.SEARCH_CANCEL_AFTER_TIME_INTERVAL_SETTING) ActionListener(org.opensearch.action.ActionListener) ClusterSettings(org.opensearch.common.settings.ClusterSettings) LogManager(org.apache.logging.log4j.LogManager) OriginSettingClient(org.opensearch.client.OriginSettingClient) CancellableTask(org.opensearch.tasks.CancellableTask) Scheduler(org.opensearch.threadpool.Scheduler) SearchService(org.opensearch.search.SearchService) TASKS_ORIGIN(org.opensearch.action.admin.cluster.node.tasks.get.GetTaskAction.TASKS_ORIGIN) TaskId(org.opensearch.tasks.TaskId) CancelTasksRequest(org.opensearch.action.admin.cluster.node.tasks.cancel.CancelTasksRequest) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) OriginSettingClient(org.opensearch.client.OriginSettingClient) TimeValue(org.opensearch.common.unit.TimeValue)

Example 2 with CancellableTask

use of org.opensearch.tasks.CancellableTask in project OpenSearch by opensearch-project.

the class CancellableTasksIT method testCancelOrphanedTasks.

public void testCancelOrphanedTasks() throws Exception {
    final String nodeWithRootTask = internalCluster().startDataOnlyNode();
    Set<DiscoveryNode> nodes = StreamSupport.stream(clusterService().state().nodes().spliterator(), false).collect(Collectors.toSet());
    TestRequest rootRequest = generateTestRequest(nodes, 0, between(1, 3));
    client(nodeWithRootTask).execute(TransportTestAction.ACTION, rootRequest);
    allowPartialRequest(rootRequest);
    try {
        internalCluster().stopRandomNode(InternalTestCluster.nameFilter(nodeWithRootTask));
        assertBusy(() -> {
            for (TransportService transportService : internalCluster().getInstances(TransportService.class)) {
                for (CancellableTask task : transportService.getTaskManager().getCancellableTasks().values()) {
                    if (task.getAction().equals(TransportTestAction.ACTION.name())) {
                        final TaskInfo taskInfo = task.taskInfo(transportService.getLocalNode().getId(), false);
                        assertTrue(taskInfo.toString(), task.isCancelled());
                        assertNotNull(taskInfo.toString(), task.getReasonCancelled());
                        assertThat(taskInfo.toString(), task.getReasonCancelled(), equalTo("channel was closed"));
                    }
                }
            }
        }, 30, TimeUnit.SECONDS);
    } finally {
        allowEntireRequest(rootRequest);
        ensureAllBansRemoved();
    }
}
Also used : TaskInfo(org.opensearch.tasks.TaskInfo) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) CancellableTask(org.opensearch.tasks.CancellableTask) TransportService(org.opensearch.transport.TransportService) Matchers.containsString(org.hamcrest.Matchers.containsString)

Example 3 with CancellableTask

use of org.opensearch.tasks.CancellableTask in project OpenSearch by opensearch-project.

the class CancellableTasksIT method testBanOnlyNodesWithOutstandingDescendantTasks.

public void testBanOnlyNodesWithOutstandingDescendantTasks() throws Exception {
    if (randomBoolean()) {
        internalCluster().startNodes(randomIntBetween(1, 3));
    }
    Set<DiscoveryNode> nodes = StreamSupport.stream(clusterService().state().nodes().spliterator(), false).collect(Collectors.toSet());
    final TestRequest rootRequest = generateTestRequest(nodes, 0, between(1, 4));
    ActionFuture<TestResponse> rootTaskFuture = client().execute(TransportTestAction.ACTION, rootRequest);
    Set<TestRequest> pendingRequests = allowPartialRequest(rootRequest);
    TaskId rootTaskId = getRootTaskId(rootRequest);
    ActionFuture<CancelTasksResponse> cancelFuture = client().admin().cluster().prepareCancelTasks().setTaskId(rootTaskId).waitForCompletion(true).execute();
    if (randomBoolean()) {
        List<TaskInfo> runningTasks = client().admin().cluster().prepareListTasks().setActions(TransportTestAction.ACTION.name()).setDetailed(true).get().getTasks();
        for (TaskInfo subTask : randomSubsetOf(runningTasks)) {
            client().admin().cluster().prepareCancelTasks().setTaskId(subTask.getTaskId()).waitForCompletion(false).get();
        }
    }
    assertBusy(() -> {
        for (DiscoveryNode node : nodes) {
            TaskManager taskManager = internalCluster().getInstance(TransportService.class, node.getName()).getTaskManager();
            Set<TaskId> expectedBans = new HashSet<>();
            for (TestRequest req : pendingRequests) {
                if (req.node.equals(node)) {
                    List<Task> childTasks = taskManager.getTasks().values().stream().filter(t -> t.getParentTaskId() != null && t.getDescription().equals(req.taskDescription())).collect(Collectors.toList());
                    assertThat(childTasks, hasSize(1));
                    CancellableTask childTask = (CancellableTask) childTasks.get(0);
                    assertTrue(childTask.isCancelled());
                    expectedBans.add(childTask.getParentTaskId());
                }
            }
            assertThat(taskManager.getBannedTaskIds(), equalTo(expectedBans));
        }
    }, 30, TimeUnit.SECONDS);
    allowEntireRequest(rootRequest);
    cancelFuture.actionGet();
    waitForRootTask(rootTaskFuture);
    ensureAllBansRemoved();
}
Also used : ActionPlugin(org.opensearch.plugins.ActionPlugin) AbstractRunnable(org.opensearch.common.util.concurrent.AbstractRunnable) ActionRequest(org.opensearch.action.ActionRequest) ConcurrentCollections(org.opensearch.common.util.concurrent.ConcurrentCollections) GroupedActionListener(org.opensearch.action.support.GroupedActionListener) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) LatchedActionListener(org.opensearch.action.LatchedActionListener) PlainActionFuture(org.opensearch.action.support.PlainActionFuture) Map(java.util.Map) Inject(org.opensearch.common.inject.Inject) ActionListener(org.opensearch.action.ActionListener) ActionResponse(org.opensearch.action.ActionResponse) ActionType(org.opensearch.action.ActionType) CancelTasksResponse(org.opensearch.action.admin.cluster.node.tasks.cancel.CancelTasksResponse) CancellableTask(org.opensearch.tasks.CancellableTask) NodeClient(org.opensearch.client.node.NodeClient) Collection(java.util.Collection) ExceptionsHelper(org.opensearch.ExceptionsHelper) Set(java.util.Set) Task(org.opensearch.tasks.Task) TransportService(org.opensearch.transport.TransportService) Collectors(java.util.stream.Collectors) TaskManager(org.opensearch.tasks.TaskManager) Objects(java.util.Objects) Matchers.instanceOf(org.hamcrest.Matchers.instanceOf) ActionFilters(org.opensearch.action.support.ActionFilters) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Matchers.equalTo(org.hamcrest.Matchers.equalTo) TaskCancelledException(org.opensearch.tasks.TaskCancelledException) Matchers.anyOf(org.hamcrest.Matchers.anyOf) OpenSearchIntegTestCase(org.opensearch.test.OpenSearchIntegTestCase) Matchers.containsString(org.hamcrest.Matchers.containsString) TransportException(org.opensearch.transport.TransportException) HandledTransportAction(org.opensearch.action.support.HandledTransportAction) ActionRunnable(org.opensearch.action.ActionRunnable) ThreadPool(org.opensearch.threadpool.ThreadPool) StreamOutput(org.opensearch.common.io.stream.StreamOutput) ResourceNotFoundException(org.opensearch.ResourceNotFoundException) InternalTestCluster(org.opensearch.test.InternalTestCluster) ActionRequestValidationException(org.opensearch.action.ActionRequestValidationException) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ListTasksResponse(org.opensearch.action.admin.cluster.node.tasks.list.ListTasksResponse) Matchers.hasSize(org.hamcrest.Matchers.hasSize) StreamSupport(java.util.stream.StreamSupport) Before(org.junit.Before) StreamInput(org.opensearch.common.io.stream.StreamInput) Matchers.empty(org.hamcrest.Matchers.empty) SetOnce(org.apache.lucene.util.SetOnce) TaskId(org.opensearch.tasks.TaskId) TransportResponseHandler(org.opensearch.transport.TransportResponseHandler) IOException(java.io.IOException) Plugin(org.opensearch.plugins.Plugin) ActionFuture(org.opensearch.action.ActionFuture) TimeUnit(java.util.concurrent.TimeUnit) Sets(org.opensearch.common.util.set.Sets) TaskInfo(org.opensearch.tasks.TaskInfo) Collections(java.util.Collections) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) CancellableTask(org.opensearch.tasks.CancellableTask) Task(org.opensearch.tasks.Task) TaskId(org.opensearch.tasks.TaskId) CancelTasksResponse(org.opensearch.action.admin.cluster.node.tasks.cancel.CancelTasksResponse) TaskInfo(org.opensearch.tasks.TaskInfo) TaskManager(org.opensearch.tasks.TaskManager) CancellableTask(org.opensearch.tasks.CancellableTask) TransportService(org.opensearch.transport.TransportService) HashSet(java.util.HashSet)

Example 4 with CancellableTask

use of org.opensearch.tasks.CancellableTask in project OpenSearch by opensearch-project.

the class CancellableTasksTests method testCancelConcurrently.

public void testCancelConcurrently() throws Exception {
    setupTestNodes(Settings.EMPTY);
    final TaskManager taskManager = testNodes[0].transportService.getTaskManager();
    int numTasks = randomIntBetween(1, 10);
    List<CancellableTask> tasks = new ArrayList<>(numTasks);
    for (int i = 0; i < numTasks; i++) {
        tasks.add((CancellableTask) taskManager.register("type-" + i, "action-" + i, new CancellableNodeRequest()));
    }
    Thread[] threads = new Thread[randomIntBetween(1, 8)];
    AtomicIntegerArray notified = new AtomicIntegerArray(threads.length);
    Phaser phaser = new Phaser(threads.length + 1);
    final CancellableTask cancellingTask = randomFrom(tasks);
    for (int i = 0; i < threads.length; i++) {
        int idx = i;
        threads[i] = new Thread(() -> {
            phaser.arriveAndAwaitAdvance();
            taskManager.cancel(cancellingTask, "test", () -> assertTrue(notified.compareAndSet(idx, 0, 1)));
        });
        threads[i].start();
    }
    phaser.arriveAndAwaitAdvance();
    taskManager.unregister(cancellingTask);
    for (int i = 0; i < threads.length; i++) {
        threads[i].join();
        assertThat(notified.get(i), equalTo(1));
    }
    AtomicBoolean called = new AtomicBoolean();
    taskManager.cancel(cancellingTask, "test", () -> assertTrue(called.compareAndSet(false, true)));
    assertTrue(called.get());
}
Also used : AtomicIntegerArray(java.util.concurrent.atomic.AtomicIntegerArray) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) TaskManager(org.opensearch.tasks.TaskManager) CancellableTask(org.opensearch.tasks.CancellableTask) ArrayList(java.util.ArrayList) Phaser(java.util.concurrent.Phaser)

Example 5 with CancellableTask

use of org.opensearch.tasks.CancellableTask in project OpenSearch by opensearch-project.

the class SearchRestCancellationIT method ensureSearchTaskIsCancelled.

private static void ensureSearchTaskIsCancelled(String transportAction, Function<String, String> nodeIdToName) throws Exception {
    SetOnce<TaskInfo> searchTask = new SetOnce<>();
    ListTasksResponse listTasksResponse = client().admin().cluster().prepareListTasks().get();
    for (TaskInfo task : listTasksResponse.getTasks()) {
        if (task.getAction().equals(transportAction)) {
            searchTask.set(task);
        }
    }
    assertNotNull(searchTask.get());
    TaskId taskId = searchTask.get().getTaskId();
    String nodeName = nodeIdToName.apply(taskId.getNodeId());
    assertBusy(() -> {
        TaskManager taskManager = internalCluster().getInstance(TransportService.class, nodeName).getTaskManager();
        Task task = taskManager.getTask(taskId.getId());
        assertThat(task, instanceOf(CancellableTask.class));
        assertTrue(((CancellableTask) task).isCancelled());
    });
}
Also used : TaskInfo(org.opensearch.tasks.TaskInfo) CancellableTask(org.opensearch.tasks.CancellableTask) Task(org.opensearch.tasks.Task) TaskId(org.opensearch.tasks.TaskId) TaskManager(org.opensearch.tasks.TaskManager) CancellableTask(org.opensearch.tasks.CancellableTask) SetOnce(org.apache.lucene.util.SetOnce) TransportService(org.opensearch.transport.TransportService) ListTasksResponse(org.opensearch.action.admin.cluster.node.tasks.list.ListTasksResponse)

Aggregations

CancellableTask (org.opensearch.tasks.CancellableTask)6 TaskId (org.opensearch.tasks.TaskId)3 TaskInfo (org.opensearch.tasks.TaskInfo)3 TaskManager (org.opensearch.tasks.TaskManager)3 TransportService (org.opensearch.transport.TransportService)3 ArrayList (java.util.ArrayList)2 TimeUnit (java.util.concurrent.TimeUnit)2 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 SetOnce (org.apache.lucene.util.SetOnce)2 Matchers.containsString (org.hamcrest.Matchers.containsString)2 ActionListener (org.opensearch.action.ActionListener)2 NodeClient (org.opensearch.client.node.NodeClient)2 DiscoveryNode (org.opensearch.cluster.node.DiscoveryNode)2 Task (org.opensearch.tasks.Task)2 ThreadPool (org.opensearch.threadpool.ThreadPool)2 IOException (java.io.IOException)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 HashSet (java.util.HashSet)1 List (java.util.List)1