Search in sources :

Example 1 with CancellableThreads

use of org.opensearch.common.util.CancellableThreads in project OpenSearch by opensearch-project.

the class SeedHostsResolver method resolveHostsLists.

/**
 * Resolves a list of hosts to a list of transport addresses. Each host is resolved into a transport address (or a collection of
 * addresses if the number of ports is greater than one). Host lookups are done in parallel using specified executor service up
 * to the specified resolve timeout.
 *
 * @param executorService  the executor service used to parallelize hostname lookups
 * @param logger           logger used for logging messages regarding hostname lookups
 * @param hosts            the hosts to resolve
 * @param transportService the transport service
 * @param resolveTimeout   the timeout before returning from hostname lookups
 * @return a list of resolved transport addresses
 */
public static List<TransportAddress> resolveHostsLists(final CancellableThreads cancellableThreads, final ExecutorService executorService, final Logger logger, final List<String> hosts, final TransportService transportService, final TimeValue resolveTimeout) {
    Objects.requireNonNull(executorService);
    Objects.requireNonNull(logger);
    Objects.requireNonNull(hosts);
    Objects.requireNonNull(transportService);
    Objects.requireNonNull(resolveTimeout);
    if (resolveTimeout.nanos() < 0) {
        throw new IllegalArgumentException("resolve timeout must be non-negative but was [" + resolveTimeout + "]");
    }
    // create tasks to submit to the executor service; we will wait up to resolveTimeout for these tasks to complete
    final List<Callable<TransportAddress[]>> callables = hosts.stream().map(hn -> (Callable<TransportAddress[]>) () -> transportService.addressesFromString(hn)).collect(Collectors.toList());
    final SetOnce<List<Future<TransportAddress[]>>> futures = new SetOnce<>();
    try {
        cancellableThreads.execute(() -> futures.set(executorService.invokeAll(callables, resolveTimeout.nanos(), TimeUnit.NANOSECONDS)));
    } catch (CancellableThreads.ExecutionCancelledException e) {
        return Collections.emptyList();
    }
    final List<TransportAddress> transportAddresses = new ArrayList<>();
    final Set<TransportAddress> localAddresses = new HashSet<>();
    localAddresses.add(transportService.boundAddress().publishAddress());
    localAddresses.addAll(Arrays.asList(transportService.boundAddress().boundAddresses()));
    // ExecutorService#invokeAll guarantees that the futures are returned in the iteration order of the tasks so we can associate the
    // hostname with the corresponding task by iterating together
    final Iterator<String> it = hosts.iterator();
    for (final Future<TransportAddress[]> future : futures.get()) {
        assert future.isDone();
        final String hostname = it.next();
        if (!future.isCancelled()) {
            try {
                final TransportAddress[] addresses = future.get();
                logger.trace("resolved host [{}] to {}", hostname, addresses);
                for (int addressId = 0; addressId < addresses.length; addressId++) {
                    final TransportAddress address = addresses[addressId];
                    // no point in pinging ourselves
                    if (localAddresses.contains(address) == false) {
                        transportAddresses.add(address);
                    }
                }
            } catch (final ExecutionException e) {
                assert e.getCause() != null;
                final String message = "failed to resolve host [" + hostname + "]";
                logger.warn(message, e.getCause());
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            // ignore
            }
        } else {
            logger.warn("timed out after [{}] resolving host [{}]", resolveTimeout, hostname);
        }
    }
    return Collections.unmodifiableList(transportAddresses);
}
Also used : CancellableThreads(org.opensearch.common.util.CancellableThreads) Arrays(java.util.Arrays) AbstractRunnable(org.opensearch.common.util.concurrent.AbstractRunnable) ThreadPool(org.opensearch.threadpool.ThreadPool) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Callable(java.util.concurrent.Callable) OpenSearchExecutors(org.opensearch.common.util.concurrent.OpenSearchExecutors) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Future(java.util.concurrent.Future) ThreadFactory(java.util.concurrent.ThreadFactory) ExecutorService(java.util.concurrent.ExecutorService) ConfiguredHostsResolver(org.opensearch.discovery.PeerFinder.ConfiguredHostsResolver) Setting(org.opensearch.common.settings.Setting) TimeValue(org.opensearch.common.unit.TimeValue) SetOnce(org.apache.lucene.util.SetOnce) Iterator(java.util.Iterator) Set(java.util.Set) Settings(org.opensearch.common.settings.Settings) TransportService(org.opensearch.transport.TransportService) Collectors(java.util.stream.Collectors) TransportAddress(org.opensearch.common.transport.TransportAddress) Objects(java.util.Objects) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) AbstractLifecycleComponent(org.opensearch.common.component.AbstractLifecycleComponent) List(java.util.List) Logger(org.apache.logging.log4j.Logger) LogManager(org.apache.logging.log4j.LogManager) Collections(java.util.Collections) CancellableThreads(org.opensearch.common.util.CancellableThreads) SetOnce(org.apache.lucene.util.SetOnce) TransportAddress(org.opensearch.common.transport.TransportAddress) ArrayList(java.util.ArrayList) Callable(java.util.concurrent.Callable) ArrayList(java.util.ArrayList) List(java.util.List) ExecutionException(java.util.concurrent.ExecutionException) HashSet(java.util.HashSet)

Example 2 with CancellableThreads

use of org.opensearch.common.util.CancellableThreads in project OpenSearch by opensearch-project.

the class PeerRecoveryTargetService method doRecovery.

private void doRecovery(final long recoveryId, final StartRecoveryRequest preExistingRequest) {
    final String actionName;
    final TransportRequest requestToSend;
    final StartRecoveryRequest startRequest;
    final RecoveryState.Timer timer;
    CancellableThreads cancellableThreads;
    try (RecoveryRef recoveryRef = onGoingRecoveries.getRecovery(recoveryId)) {
        if (recoveryRef == null) {
            logger.trace("not running recovery with id [{}] - can not find it (probably finished)", recoveryId);
            return;
        }
        final RecoveryTarget recoveryTarget = recoveryRef.target();
        timer = recoveryTarget.state().getTimer();
        cancellableThreads = recoveryTarget.cancellableThreads();
        if (preExistingRequest == null) {
            try {
                final IndexShard indexShard = recoveryTarget.indexShard();
                indexShard.preRecovery();
                assert recoveryTarget.sourceNode() != null : "can not do a recovery without a source node";
                logger.trace("{} preparing shard for peer recovery", recoveryTarget.shardId());
                indexShard.prepareForIndexRecovery();
                final long startingSeqNo = indexShard.recoverLocallyUpToGlobalCheckpoint();
                assert startingSeqNo == UNASSIGNED_SEQ_NO || recoveryTarget.state().getStage() == RecoveryState.Stage.TRANSLOG : "unexpected recovery stage [" + recoveryTarget.state().getStage() + "] starting seqno [ " + startingSeqNo + "]";
                startRequest = getStartRecoveryRequest(logger, clusterService.localNode(), recoveryTarget, startingSeqNo);
                requestToSend = startRequest;
                actionName = PeerRecoverySourceService.Actions.START_RECOVERY;
            } catch (final Exception e) {
                // this will be logged as warning later on...
                logger.trace("unexpected error while preparing shard for peer recovery, failing recovery", e);
                onGoingRecoveries.failRecovery(recoveryId, new RecoveryFailedException(recoveryTarget.state(), "failed to prepare shard for recovery", e), true);
                return;
            }
            logger.trace("{} starting recovery from {}", startRequest.shardId(), startRequest.sourceNode());
        } else {
            startRequest = preExistingRequest;
            requestToSend = new ReestablishRecoveryRequest(recoveryId, startRequest.shardId(), startRequest.targetAllocationId());
            actionName = PeerRecoverySourceService.Actions.REESTABLISH_RECOVERY;
            logger.trace("{} reestablishing recovery from {}", startRequest.shardId(), startRequest.sourceNode());
        }
    }
    RecoveryResponseHandler responseHandler = new RecoveryResponseHandler(startRequest, timer);
    try {
        cancellableThreads.executeIO(() -> transportService.sendRequest(startRequest.sourceNode(), actionName, requestToSend, responseHandler));
    } catch (CancellableThreads.ExecutionCancelledException e) {
        logger.trace("recovery cancelled", e);
    } catch (Exception e) {
        responseHandler.onException(e);
    }
}
Also used : CancellableThreads(org.opensearch.common.util.CancellableThreads) TransportRequest(org.opensearch.transport.TransportRequest) IndexShard(org.opensearch.index.shard.IndexShard) TranslogCorruptedException(org.opensearch.index.translog.TranslogCorruptedException) AlreadyClosedException(org.apache.lucene.store.AlreadyClosedException) RecoveryEngineException(org.opensearch.index.engine.RecoveryEngineException) OpenSearchException(org.opensearch.OpenSearchException) MapperException(org.opensearch.index.mapper.MapperException) OpenSearchTimeoutException(org.opensearch.OpenSearchTimeoutException) ConnectTransportException(org.opensearch.transport.ConnectTransportException) TransportException(org.opensearch.transport.TransportException) IllegalIndexShardStateException(org.opensearch.index.shard.IllegalIndexShardStateException) IndexNotFoundException(org.opensearch.index.IndexNotFoundException) IOException(java.io.IOException) ShardNotFoundException(org.opensearch.index.shard.ShardNotFoundException) RecoveryRef(org.opensearch.indices.recovery.RecoveriesCollection.RecoveryRef)

Example 3 with CancellableThreads

use of org.opensearch.common.util.CancellableThreads in project OpenSearch by opensearch-project.

the class FileBasedSeedHostsProviderTests method setupAndRunHostProvider.

// sets up the config dir, writes to the unicast hosts file in the config dir,
// and then runs the file-based unicast host provider to get the list of discovery nodes
private List<TransportAddress> setupAndRunHostProvider(final List<String> hostEntries) throws IOException {
    final Path homeDir = createTempDir();
    final Path configPath = randomBoolean() ? homeDir.resolve("config") : createTempDir();
    Files.createDirectories(configPath);
    try (BufferedWriter writer = Files.newBufferedWriter(configPath.resolve(UNICAST_HOSTS_FILE))) {
        writer.write(String.join("\n", hostEntries));
    }
    return new FileBasedSeedHostsProvider(configPath).getSeedAddresses(hosts -> SeedHostsResolver.resolveHostsLists(new CancellableThreads(), executorService, logger, hosts, transportService, TimeValue.timeValueSeconds(10)));
}
Also used : Path(java.nio.file.Path) CancellableThreads(org.opensearch.common.util.CancellableThreads) BufferedWriter(java.io.BufferedWriter)

Example 4 with CancellableThreads

use of org.opensearch.common.util.CancellableThreads in project OpenSearch by opensearch-project.

the class SeedHostsResolverTests method testUnknownHost.

public void testUnknownHost() {
    final Logger logger = mock(Logger.class);
    final NetworkService networkService = new NetworkService(Collections.emptyList());
    final String hostname = randomAlphaOfLength(8);
    final UnknownHostException unknownHostException = new UnknownHostException(hostname);
    final Transport transport = new MockNioTransport(Settings.EMPTY, Version.CURRENT, threadPool, networkService, PageCacheRecycler.NON_RECYCLING_INSTANCE, new NamedWriteableRegistry(Collections.emptyList()), new NoneCircuitBreakerService()) {

        @Override
        public BoundTransportAddress boundAddress() {
            return new BoundTransportAddress(new TransportAddress[] { new TransportAddress(InetAddress.getLoopbackAddress(), 9300) }, new TransportAddress(InetAddress.getLoopbackAddress(), 9300));
        }

        @Override
        public TransportAddress[] addressesFromString(String address) throws UnknownHostException {
            throw unknownHostException;
        }
    };
    closeables.push(transport);
    final TransportService transportService = new TransportService(Settings.EMPTY, transport, threadPool, TransportService.NOOP_TRANSPORT_INTERCEPTOR, x -> null, null, Collections.emptySet());
    closeables.push(transportService);
    final List<TransportAddress> transportAddresses = SeedHostsResolver.resolveHostsLists(new CancellableThreads(), executorService, logger, Arrays.asList(hostname), transportService, TimeValue.timeValueSeconds(30));
    assertThat(transportAddresses, empty());
    verify(logger).warn("failed to resolve host [" + hostname + "]", unknownHostException);
}
Also used : NamedWriteableRegistry(org.opensearch.common.io.stream.NamedWriteableRegistry) CancellableThreads(org.opensearch.common.util.CancellableThreads) UnknownHostException(java.net.UnknownHostException) BoundTransportAddress(org.opensearch.common.transport.BoundTransportAddress) TransportAddress(org.opensearch.common.transport.TransportAddress) Logger(org.apache.logging.log4j.Logger) TransportService(org.opensearch.transport.TransportService) BoundTransportAddress(org.opensearch.common.transport.BoundTransportAddress) NetworkService(org.opensearch.common.network.NetworkService) MockNioTransport(org.opensearch.transport.nio.MockNioTransport) Transport(org.opensearch.transport.Transport) MockNioTransport(org.opensearch.transport.nio.MockNioTransport) NoneCircuitBreakerService(org.opensearch.indices.breaker.NoneCircuitBreakerService)

Example 5 with CancellableThreads

use of org.opensearch.common.util.CancellableThreads in project OpenSearch by opensearch-project.

the class SeedHostsResolverTests method testInvalidHosts.

public void testInvalidHosts() throws IllegalAccessException {
    final Logger logger = mock(Logger.class);
    final Transport transport = new MockNioTransport(Settings.EMPTY, Version.CURRENT, threadPool, new NetworkService(Collections.emptyList()), PageCacheRecycler.NON_RECYCLING_INSTANCE, new NamedWriteableRegistry(Collections.emptyList()), new NoneCircuitBreakerService()) {

        @Override
        public BoundTransportAddress boundAddress() {
            return new BoundTransportAddress(new TransportAddress[] { new TransportAddress(InetAddress.getLoopbackAddress(), 9300) }, new TransportAddress(InetAddress.getLoopbackAddress(), 9300));
        }
    };
    closeables.push(transport);
    final TransportService transportService = new TransportService(Settings.EMPTY, transport, threadPool, TransportService.NOOP_TRANSPORT_INTERCEPTOR, x -> null, null, Collections.emptySet());
    closeables.push(transportService);
    final List<TransportAddress> transportAddresses = SeedHostsResolver.resolveHostsLists(new CancellableThreads(), executorService, logger, Arrays.asList("127.0.0.1:9300:9300", "127.0.0.1:9301"), transportService, TimeValue.timeValueSeconds(30));
    // only one of the two is valid and will be used
    assertThat(transportAddresses, hasSize(1));
    assertThat(transportAddresses.get(0).getAddress(), equalTo("127.0.0.1"));
    assertThat(transportAddresses.get(0).getPort(), equalTo(9301));
    verify(logger).warn(eq("failed to resolve host [127.0.0.1:9300:9300]"), Mockito.any(IllegalArgumentException.class));
}
Also used : NamedWriteableRegistry(org.opensearch.common.io.stream.NamedWriteableRegistry) CancellableThreads(org.opensearch.common.util.CancellableThreads) TransportService(org.opensearch.transport.TransportService) BoundTransportAddress(org.opensearch.common.transport.BoundTransportAddress) TransportAddress(org.opensearch.common.transport.TransportAddress) BoundTransportAddress(org.opensearch.common.transport.BoundTransportAddress) MockNioTransport(org.opensearch.transport.nio.MockNioTransport) NetworkService(org.opensearch.common.network.NetworkService) Logger(org.apache.logging.log4j.Logger) Transport(org.opensearch.transport.Transport) MockNioTransport(org.opensearch.transport.nio.MockNioTransport) NoneCircuitBreakerService(org.opensearch.indices.breaker.NoneCircuitBreakerService)

Aggregations

CancellableThreads (org.opensearch.common.util.CancellableThreads)10 Logger (org.apache.logging.log4j.Logger)7 TransportAddress (org.opensearch.common.transport.TransportAddress)5 TimeValue (org.opensearch.common.unit.TimeValue)5 TransportService (org.opensearch.transport.TransportService)5 IOException (java.io.IOException)4 ArrayList (java.util.ArrayList)4 Arrays (java.util.Arrays)4 Collections (java.util.Collections)4 List (java.util.List)4 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)4 NamedWriteableRegistry (org.opensearch.common.io.stream.NamedWriteableRegistry)4 NetworkService (org.opensearch.common.network.NetworkService)4 BoundTransportAddress (org.opensearch.common.transport.BoundTransportAddress)4 OpenSearchExecutors (org.opensearch.common.util.concurrent.OpenSearchExecutors)4 IndexShard (org.opensearch.index.shard.IndexShard)4 NoneCircuitBreakerService (org.opensearch.indices.breaker.NoneCircuitBreakerService)4 ThreadPool (org.opensearch.threadpool.ThreadPool)4 Transport (org.opensearch.transport.Transport)4 MockNioTransport (org.opensearch.transport.nio.MockNioTransport)4