Search in sources :

Example 21 with ClusterStateUpdateTask

use of org.opensearch.cluster.ClusterStateUpdateTask in project OpenSearch by opensearch-project.

the class BlockMasterServiceOnMaster method startDisrupting.

@Override
public void startDisrupting() {
    disruptedNode = cluster.getMasterName();
    final String disruptionNodeCopy = disruptedNode;
    if (disruptionNodeCopy == null) {
        return;
    }
    ClusterService clusterService = cluster.getInstance(ClusterService.class, disruptionNodeCopy);
    if (clusterService == null) {
        return;
    }
    logger.info("blocking master service on node [{}]", disruptionNodeCopy);
    boolean success = disruptionLatch.compareAndSet(null, new CountDownLatch(1));
    assert success : "startDisrupting called without waiting on stopDisrupting to complete";
    final CountDownLatch started = new CountDownLatch(1);
    clusterService.getMasterService().submitStateUpdateTask("service_disruption_block", new ClusterStateUpdateTask() {

        @Override
        public Priority priority() {
            return Priority.IMMEDIATE;
        }

        @Override
        public ClusterState execute(ClusterState currentState) throws Exception {
            started.countDown();
            CountDownLatch latch = disruptionLatch.get();
            if (latch != null) {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    Throwables.rethrow(e);
                }
            }
            return currentState;
        }

        @Override
        public void onFailure(String source, Exception e) {
            logger.error("unexpected error during disruption", e);
        }
    });
    try {
        started.await();
    } catch (InterruptedException e) {
    }
}
Also used : ClusterState(org.opensearch.cluster.ClusterState) ClusterService(org.opensearch.cluster.service.ClusterService) Priority(org.opensearch.common.Priority) ClusterStateUpdateTask(org.opensearch.cluster.ClusterStateUpdateTask) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 22 with ClusterStateUpdateTask

use of org.opensearch.cluster.ClusterStateUpdateTask in project OpenSearch by opensearch-project.

the class FakeThreadPoolMasterServiceTests method testFakeMasterService.

public void testFakeMasterService() {
    List<Runnable> runnableTasks = new ArrayList<>();
    AtomicReference<ClusterState> lastClusterStateRef = new AtomicReference<>();
    DiscoveryNode discoveryNode = new DiscoveryNode("node", OpenSearchTestCase.buildNewFakeTransportAddress(), Collections.emptyMap(), new HashSet<>(DiscoveryNodeRole.BUILT_IN_ROLES), Version.CURRENT);
    lastClusterStateRef.set(ClusterStateCreationUtils.state(discoveryNode, discoveryNode));
    long firstClusterStateVersion = lastClusterStateRef.get().version();
    AtomicReference<ActionListener<Void>> publishingCallback = new AtomicReference<>();
    final ThreadContext context = new ThreadContext(Settings.EMPTY);
    final ThreadPool mockThreadPool = mock(ThreadPool.class);
    when(mockThreadPool.getThreadContext()).thenReturn(context);
    final ExecutorService executorService = mock(ExecutorService.class);
    doAnswer(invocationOnMock -> runnableTasks.add((Runnable) invocationOnMock.getArguments()[0])).when(executorService).execute(any());
    when(mockThreadPool.generic()).thenReturn(executorService);
    FakeThreadPoolMasterService masterService = new FakeThreadPoolMasterService("test_node", "test", mockThreadPool, runnableTasks::add);
    masterService.setClusterStateSupplier(lastClusterStateRef::get);
    masterService.setClusterStatePublisher((event, publishListener, ackListener) -> {
        lastClusterStateRef.set(event.state());
        publishingCallback.set(publishListener);
    });
    masterService.start();
    AtomicBoolean firstTaskCompleted = new AtomicBoolean();
    masterService.submitStateUpdateTask("test1", new ClusterStateUpdateTask() {

        @Override
        public ClusterState execute(ClusterState currentState) {
            return ClusterState.builder(currentState).metadata(Metadata.builder(currentState.metadata()).put(indexBuilder("test1"))).build();
        }

        @Override
        public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
            assertFalse(firstTaskCompleted.get());
            firstTaskCompleted.set(true);
        }

        @Override
        public void onFailure(String source, Exception e) {
            throw new AssertionError();
        }
    });
    assertThat(runnableTasks.size(), equalTo(1));
    assertThat(lastClusterStateRef.get().metadata().indices().size(), equalTo(0));
    assertThat(lastClusterStateRef.get().version(), equalTo(firstClusterStateVersion));
    assertNull(publishingCallback.get());
    assertFalse(firstTaskCompleted.get());
    final Runnable scheduleTask = runnableTasks.remove(0);
    assertThat(scheduleTask, hasToString("master service scheduling next task"));
    scheduleTask.run();
    final Runnable publishTask = runnableTasks.remove(0);
    assertThat(publishTask, hasToString(containsString("publish change of cluster state")));
    publishTask.run();
    assertThat(lastClusterStateRef.get().metadata().indices().size(), equalTo(1));
    assertThat(lastClusterStateRef.get().version(), equalTo(firstClusterStateVersion + 1));
    assertNotNull(publishingCallback.get());
    assertFalse(firstTaskCompleted.get());
    assertThat(runnableTasks.size(), equalTo(0));
    AtomicBoolean secondTaskCompleted = new AtomicBoolean();
    masterService.submitStateUpdateTask("test2", new ClusterStateUpdateTask() {

        @Override
        public ClusterState execute(ClusterState currentState) {
            return ClusterState.builder(currentState).metadata(Metadata.builder(currentState.metadata()).put(indexBuilder("test2"))).build();
        }

        @Override
        public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
            assertFalse(secondTaskCompleted.get());
            secondTaskCompleted.set(true);
        }

        @Override
        public void onFailure(String source, Exception e) {
            throw new AssertionError();
        }
    });
    assertThat(runnableTasks.size(), equalTo(0));
    publishingCallback.getAndSet(null).onResponse(null);
    assertTrue(firstTaskCompleted.get());
    // check that new task gets queued
    assertThat(runnableTasks.size(), equalTo(1));
    // schedule again
    runnableTasks.remove(0).run();
    // publish again
    runnableTasks.remove(0).run();
    assertThat(lastClusterStateRef.get().metadata().indices().size(), equalTo(2));
    assertThat(lastClusterStateRef.get().version(), equalTo(firstClusterStateVersion + 2));
    assertNotNull(publishingCallback.get());
    assertFalse(secondTaskCompleted.get());
    publishingCallback.getAndSet(null).onResponse(null);
    assertTrue(secondTaskCompleted.get());
    // check that no more tasks are queued
    assertThat(runnableTasks.size(), equalTo(0));
}
Also used : ClusterState(org.opensearch.cluster.ClusterState) DiscoveryNode(org.opensearch.cluster.node.DiscoveryNode) ArrayList(java.util.ArrayList) ThreadContext(org.opensearch.common.util.concurrent.ThreadContext) ThreadPool(org.opensearch.threadpool.ThreadPool) ClusterStateUpdateTask(org.opensearch.cluster.ClusterStateUpdateTask) AtomicReference(java.util.concurrent.atomic.AtomicReference) Matchers.hasToString(org.hamcrest.Matchers.hasToString) Matchers.containsString(org.hamcrest.Matchers.containsString) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ActionListener(org.opensearch.action.ActionListener) ExecutorService(java.util.concurrent.ExecutorService)

Example 23 with ClusterStateUpdateTask

use of org.opensearch.cluster.ClusterStateUpdateTask in project OpenSearch by opensearch-project.

the class DynamicMappingIT method testPreflightCheckAvoidsMaster.

public void testPreflightCheckAvoidsMaster() throws InterruptedException {
    createIndex("index", Settings.builder().put(INDEX_MAPPING_TOTAL_FIELDS_LIMIT_SETTING.getKey(), 2).build());
    ensureGreen("index");
    client().prepareIndex("index").setId("1").setSource("field1", "value1").get();
    final CountDownLatch masterBlockedLatch = new CountDownLatch(1);
    final CountDownLatch indexingCompletedLatch = new CountDownLatch(1);
    internalCluster().getInstance(ClusterService.class, internalCluster().getMasterName()).submitStateUpdateTask("block-state-updates", new ClusterStateUpdateTask() {

        @Override
        public ClusterState execute(ClusterState currentState) throws Exception {
            masterBlockedLatch.countDown();
            indexingCompletedLatch.await();
            return currentState;
        }

        @Override
        public void onFailure(String source, Exception e) {
            throw new AssertionError("unexpected", e);
        }
    });
    masterBlockedLatch.await();
    final IndexRequestBuilder indexRequestBuilder = client().prepareIndex("index").setId("2").setSource("field2", "value2");
    try {
        assertThat(expectThrows(IllegalArgumentException.class, () -> indexRequestBuilder.get(TimeValue.timeValueSeconds(10))).getMessage(), Matchers.containsString("Limit of total fields [2] has been exceeded"));
    } finally {
        indexingCompletedLatch.countDown();
    }
}
Also used : IndexRequestBuilder(org.opensearch.action.index.IndexRequestBuilder) ClusterState(org.opensearch.cluster.ClusterState) ClusterService(org.opensearch.cluster.service.ClusterService) ClusterStateUpdateTask(org.opensearch.cluster.ClusterStateUpdateTask) CountDownLatch(java.util.concurrent.CountDownLatch) IOException(java.io.IOException)

Example 24 with ClusterStateUpdateTask

use of org.opensearch.cluster.ClusterStateUpdateTask in project OpenSearch by opensearch-project.

the class TransportAddVotingConfigExclusionsAction method masterOperation.

@Override
protected void masterOperation(AddVotingConfigExclusionsRequest request, ClusterState state, ActionListener<AddVotingConfigExclusionsResponse> listener) throws Exception {
    resolveVotingConfigExclusionsAndCheckMaximum(request, state, maxVotingConfigExclusions);
    // throws IAE if no nodes matched or maximum exceeded
    clusterService.submitStateUpdateTask("add-voting-config-exclusions", new ClusterStateUpdateTask(Priority.URGENT) {

        private Set<VotingConfigExclusion> resolvedExclusions;

        @Override
        public ClusterState execute(ClusterState currentState) {
            assert resolvedExclusions == null : resolvedExclusions;
            final int finalMaxVotingConfigExclusions = TransportAddVotingConfigExclusionsAction.this.maxVotingConfigExclusions;
            resolvedExclusions = resolveVotingConfigExclusionsAndCheckMaximum(request, currentState, finalMaxVotingConfigExclusions);
            final CoordinationMetadata.Builder builder = CoordinationMetadata.builder(currentState.coordinationMetadata());
            resolvedExclusions.forEach(builder::addVotingConfigExclusion);
            final Metadata newMetadata = Metadata.builder(currentState.metadata()).coordinationMetadata(builder.build()).build();
            final ClusterState newState = ClusterState.builder(currentState).metadata(newMetadata).build();
            assert newState.getVotingConfigExclusions().size() <= finalMaxVotingConfigExclusions;
            return newState;
        }

        @Override
        public void onFailure(String source, Exception e) {
            listener.onFailure(e);
        }

        @Override
        public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
            final ClusterStateObserver observer = new ClusterStateObserver(clusterService, request.getTimeout(), logger, threadPool.getThreadContext());
            final Set<String> excludedNodeIds = resolvedExclusions.stream().map(VotingConfigExclusion::getNodeId).collect(Collectors.toSet());
            final Predicate<ClusterState> allNodesRemoved = clusterState -> {
                final Set<String> votingConfigNodeIds = clusterState.getLastCommittedConfiguration().getNodeIds();
                return excludedNodeIds.stream().noneMatch(votingConfigNodeIds::contains);
            };
            final Listener clusterStateListener = new Listener() {

                @Override
                public void onNewClusterState(ClusterState state) {
                    listener.onResponse(new AddVotingConfigExclusionsResponse());
                }

                @Override
                public void onClusterServiceClose() {
                    listener.onFailure(new OpenSearchException("cluster service closed while waiting for voting config exclusions " + resolvedExclusions + " to take effect"));
                }

                @Override
                public void onTimeout(TimeValue timeout) {
                    listener.onFailure(new OpenSearchTimeoutException("timed out waiting for voting config exclusions " + resolvedExclusions + " to take effect"));
                }
            };
            if (allNodesRemoved.test(newState)) {
                clusterStateListener.onNewClusterState(newState);
            } else {
                observer.waitForNextChange(clusterStateListener, allNodesRemoved);
            }
        }
    });
}
Also used : VotingConfigExclusion(org.opensearch.cluster.coordination.CoordinationMetadata.VotingConfigExclusion) ClusterState(org.opensearch.cluster.ClusterState) ClusterStateObserver(org.opensearch.cluster.ClusterStateObserver) Set(java.util.Set) ActionListener(org.opensearch.action.ActionListener) Listener(org.opensearch.cluster.ClusterStateObserver.Listener) OpenSearchTimeoutException(org.opensearch.OpenSearchTimeoutException) Metadata(org.opensearch.cluster.metadata.Metadata) CoordinationMetadata(org.opensearch.cluster.coordination.CoordinationMetadata) ClusterStateUpdateTask(org.opensearch.cluster.ClusterStateUpdateTask) OpenSearchException(org.opensearch.OpenSearchException) ClusterBlockException(org.opensearch.cluster.block.ClusterBlockException) IOException(java.io.IOException) OpenSearchTimeoutException(org.opensearch.OpenSearchTimeoutException) Predicate(java.util.function.Predicate) OpenSearchException(org.opensearch.OpenSearchException) TimeValue(org.opensearch.common.unit.TimeValue)

Example 25 with ClusterStateUpdateTask

use of org.opensearch.cluster.ClusterStateUpdateTask in project OpenSearch by opensearch-project.

the class TransportClusterHealthAction method waitForEventsAndExecuteHealth.

private void waitForEventsAndExecuteHealth(final ClusterHealthRequest request, final ActionListener<ClusterHealthResponse> listener, final int waitCount, final long endTimeRelativeMillis) {
    assert request.waitForEvents() != null;
    if (request.local()) {
        clusterService.submitStateUpdateTask("cluster_health (wait_for_events [" + request.waitForEvents() + "])", new LocalClusterUpdateTask(request.waitForEvents()) {

            @Override
            public ClusterTasksResult<LocalClusterUpdateTask> execute(ClusterState currentState) {
                return unchanged();
            }

            @Override
            public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
                final long timeoutInMillis = Math.max(0, endTimeRelativeMillis - threadPool.relativeTimeInMillis());
                final TimeValue newTimeout = TimeValue.timeValueMillis(timeoutInMillis);
                request.timeout(newTimeout);
                executeHealth(request, clusterService.state(), listener, waitCount, observedState -> waitForEventsAndExecuteHealth(request, listener, waitCount, endTimeRelativeMillis));
            }

            @Override
            public void onFailure(String source, Exception e) {
                logger.error(() -> new ParameterizedMessage("unexpected failure during [{}]", source), e);
                listener.onFailure(e);
            }
        });
    } else {
        final TimeValue taskTimeout = TimeValue.timeValueMillis(Math.max(0, endTimeRelativeMillis - threadPool.relativeTimeInMillis()));
        clusterService.submitStateUpdateTask("cluster_health (wait_for_events [" + request.waitForEvents() + "])", new ClusterStateUpdateTask(request.waitForEvents()) {

            @Override
            public ClusterState execute(ClusterState currentState) {
                return currentState;
            }

            @Override
            public TimeValue timeout() {
                return taskTimeout;
            }

            @Override
            public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
                final long timeoutInMillis = Math.max(0, endTimeRelativeMillis - threadPool.relativeTimeInMillis());
                final TimeValue newTimeout = TimeValue.timeValueMillis(timeoutInMillis);
                request.timeout(newTimeout);
                // we must use the state from the applier service, because if the state-not-recovered block is in place then the
                // applier service has a different view of the cluster state from the one supplied here
                final ClusterState appliedState = clusterService.state();
                assert newState.stateUUID().equals(appliedState.stateUUID()) : newState.stateUUID() + " vs " + appliedState.stateUUID();
                executeHealth(request, appliedState, listener, waitCount, observedState -> waitForEventsAndExecuteHealth(request, listener, waitCount, endTimeRelativeMillis));
            }

            @Override
            public void onNoLongerMaster(String source) {
                logger.trace("stopped being master while waiting for events with priority [{}]. retrying.", request.waitForEvents());
                // TransportMasterNodeAction implements the retry logic, which is triggered by passing a NotMasterException
                listener.onFailure(new NotMasterException("no longer master. source: [" + source + "]"));
            }

            @Override
            public void onFailure(String source, Exception e) {
                if (e instanceof ProcessClusterEventTimeoutException) {
                    listener.onResponse(getResponse(request, clusterService.state(), waitCount, TimeoutState.TIMED_OUT));
                } else {
                    logger.error(() -> new ParameterizedMessage("unexpected failure during [{}]", source), e);
                    listener.onFailure(e);
                }
            }
        });
    }
}
Also used : ThreadPool(org.opensearch.threadpool.ThreadPool) AllocationService(org.opensearch.cluster.routing.allocation.AllocationService) IndicesOptions(org.opensearch.action.support.IndicesOptions) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) Strings(org.opensearch.common.Strings) ClusterState(org.opensearch.cluster.ClusterState) NotMasterException(org.opensearch.cluster.NotMasterException) NodeClosedException(org.opensearch.node.NodeClosedException) Inject(org.opensearch.common.inject.Inject) ActionListener(org.opensearch.action.ActionListener) ClusterStateObserver(org.opensearch.cluster.ClusterStateObserver) UnassignedInfo(org.opensearch.cluster.routing.UnassignedInfo) ClusterHealthStatus(org.opensearch.cluster.health.ClusterHealthStatus) ProcessClusterEventTimeoutException(org.opensearch.cluster.metadata.ProcessClusterEventTimeoutException) StreamInput(org.opensearch.common.io.stream.StreamInput) TimeValue(org.opensearch.common.unit.TimeValue) CollectionUtils(org.opensearch.common.util.CollectionUtils) Predicate(java.util.function.Predicate) IndexNotFoundException(org.opensearch.index.IndexNotFoundException) ClusterBlockException(org.opensearch.cluster.block.ClusterBlockException) IOException(java.io.IOException) Task(org.opensearch.tasks.Task) TransportService(org.opensearch.transport.TransportService) ActiveShardCount(org.opensearch.action.support.ActiveShardCount) LocalClusterUpdateTask(org.opensearch.cluster.LocalClusterUpdateTask) Consumer(java.util.function.Consumer) ActionFilters(org.opensearch.action.support.ActionFilters) Logger(org.apache.logging.log4j.Logger) ClusterStateUpdateTask(org.opensearch.cluster.ClusterStateUpdateTask) ClusterService(org.opensearch.cluster.service.ClusterService) LogManager(org.apache.logging.log4j.LogManager) TransportMasterNodeReadAction(org.opensearch.action.support.master.TransportMasterNodeReadAction) IndexNameExpressionResolver(org.opensearch.cluster.metadata.IndexNameExpressionResolver) ClusterState(org.opensearch.cluster.ClusterState) LocalClusterUpdateTask(org.opensearch.cluster.LocalClusterUpdateTask) ProcessClusterEventTimeoutException(org.opensearch.cluster.metadata.ProcessClusterEventTimeoutException) ClusterStateUpdateTask(org.opensearch.cluster.ClusterStateUpdateTask) ParameterizedMessage(org.apache.logging.log4j.message.ParameterizedMessage) NotMasterException(org.opensearch.cluster.NotMasterException) TimeValue(org.opensearch.common.unit.TimeValue) NotMasterException(org.opensearch.cluster.NotMasterException) NodeClosedException(org.opensearch.node.NodeClosedException) ProcessClusterEventTimeoutException(org.opensearch.cluster.metadata.ProcessClusterEventTimeoutException) IndexNotFoundException(org.opensearch.index.IndexNotFoundException) ClusterBlockException(org.opensearch.cluster.block.ClusterBlockException) IOException(java.io.IOException)

Aggregations

ClusterStateUpdateTask (org.opensearch.cluster.ClusterStateUpdateTask)44 ClusterState (org.opensearch.cluster.ClusterState)43 IOException (java.io.IOException)21 ClusterService (org.opensearch.cluster.service.ClusterService)21 TimeValue (org.opensearch.common.unit.TimeValue)20 ActionListener (org.opensearch.action.ActionListener)18 ParameterizedMessage (org.apache.logging.log4j.message.ParameterizedMessage)17 ArrayList (java.util.ArrayList)16 List (java.util.List)16 Set (java.util.Set)15 ThreadPool (org.opensearch.threadpool.ThreadPool)14 HashSet (java.util.HashSet)13 Map (java.util.Map)13 ClusterBlockException (org.opensearch.cluster.block.ClusterBlockException)13 IndexMetadata (org.opensearch.cluster.metadata.IndexMetadata)13 Metadata (org.opensearch.cluster.metadata.Metadata)13 Collections (java.util.Collections)12 Collectors (java.util.stream.Collectors)12 LogManager (org.apache.logging.log4j.LogManager)12 Logger (org.apache.logging.log4j.Logger)12