public void testThreadContextRestored() throws Exception {
   String header = randomAsciiOfLength(5);
   threadPool.getThreadContext().putHeader("test", header);
   AtomicBoolean called = new AtomicBoolean();
   sourceWithMockedRemoteCall("start_ok.json")
       .doStart(
           r -> {
             assertEquals(header, threadPool.getThreadContext().getHeader("test"));
             called.set(true);
           });
   assertTrue(called.get());
 }
  public <T extends TransportResponse> void sendRequest(
      final DiscoveryNode node,
      final String action,
      final TransportRequest request,
      final TransportRequestOptions options,
      TransportResponseHandler<T> handler) {
    if (node == null) {
      throw new ElasticsearchIllegalStateException("can't send request to a null node");
    }
    final long requestId = newRequestId();
    TimeoutHandler timeoutHandler = null;
    try {
      clientHandlers.put(requestId, new RequestHolder<>(handler, node, action, timeoutHandler));
      if (started.get() == false) {
        // if we are not started the exception handling will remove the RequestHolder again and
        // calls the handler to notify the caller.
        // it will only notify if the toStop code hasn't done the work yet.
        throw new TransportException("TransportService is closed stopped can't send request");
      }
      if (options.timeout() != null) {
        timeoutHandler = new TimeoutHandler(requestId);
        timeoutHandler.future =
            threadPool.schedule(options.timeout(), ThreadPool.Names.GENERIC, timeoutHandler);
      }
      transport.sendRequest(node, requestId, action, request, options);
    } catch (final Throwable e) {
      // usually happen either because we failed to connect to the node
      // or because we failed serializing the message
      final RequestHolder holderToNotify = clientHandlers.remove(requestId);
      // if the scheduler raise a EsRejectedExecutionException (due to shutdown), we may have a
      // timeout handler, but no future
      if (timeoutHandler != null) {
        FutureUtils.cancel(timeoutHandler.future);
      }

      // If holderToNotify == null then handler has already been taken care of.
      if (holderToNotify != null) {
        // callback that an exception happened, but on a different thread since we don't
        // want handlers to worry about stack overflows
        final SendRequestTransportException sendRequestException =
            new SendRequestTransportException(node, action, e);
        threadPool
            .executor(ThreadPool.Names.GENERIC)
            .execute(
                new Runnable() {
                  @Override
                  public void run() {
                    holderToNotify.handler().handleException(sendRequestException);
                  }
                });
      }
    }
  }
 @Override
 public BloomFilter filter(IndexReader reader, String fieldName, boolean asyncLoad) {
   int currentNumDocs = reader.numDocs();
   if (currentNumDocs == 0) {
     return BloomFilter.EMPTY;
   }
   ConcurrentMap<String, BloomFilterEntry> fieldCache = cache.get(reader.getFieldCacheKey());
   if (fieldCache == null) {
     synchronized (creationMutex) {
       fieldCache = cache.get(reader.getFieldCacheKey());
       if (fieldCache == null) {
         fieldCache = ConcurrentCollections.newConcurrentMap();
         cache.put(reader.getFieldCacheKey(), fieldCache);
       }
     }
   }
   BloomFilterEntry filter = fieldCache.get(fieldName);
   if (filter == null) {
     synchronized (fieldCache) {
       filter = fieldCache.get(fieldName);
       if (filter == null) {
         filter = new BloomFilterEntry(reader.numDocs(), BloomFilter.NONE);
         filter.loading.set(true);
         fieldCache.put(fieldName, filter);
         // now, do the async load of it...
         BloomFilterLoader loader = new BloomFilterLoader(reader, fieldName);
         if (asyncLoad) {
           threadPool.cached().execute(loader);
         } else {
           loader.run();
           filter = fieldCache.get(fieldName);
         }
       }
     }
   }
   // if we too many deletes, we need to reload the bloom filter so it will be more effective
   if (filter.numDocs > 1000 && (currentNumDocs / filter.numDocs) < 0.6) {
     if (filter.loading.compareAndSet(false, true)) {
       // do the async loading
       BloomFilterLoader loader = new BloomFilterLoader(reader, fieldName);
       if (asyncLoad) {
         threadPool.cached().execute(loader);
       } else {
         loader.run();
         filter = fieldCache.get(fieldName);
       }
     }
   }
   return filter.filter;
 }
  public void testScalingExecutorType() throws InterruptedException {
    String threadPoolName = randomThreadPool(ThreadPool.ThreadPoolType.SCALING);
    ThreadPool threadPool = null;
    try {
      Settings nodeSettings =
          Settings.builder()
              .put("threadpool." + threadPoolName + ".size", 10)
              .put("node.name", "testScalingExecutorType")
              .build();
      threadPool = new ThreadPool(nodeSettings);
      ClusterSettings clusterSettings =
          new ClusterSettings(nodeSettings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
      threadPool.setClusterSettings(clusterSettings);
      final int expectedMinimum = "generic".equals(threadPoolName) ? 4 : 1;
      assertThat(info(threadPool, threadPoolName).getMin(), equalTo(expectedMinimum));
      assertThat(info(threadPool, threadPoolName).getMax(), equalTo(10));
      final long expectedKeepAlive = "generic".equals(threadPoolName) ? 30 : 300;
      assertThat(
          info(threadPool, threadPoolName).getKeepAlive().seconds(), equalTo(expectedKeepAlive));
      assertEquals(
          info(threadPool, threadPoolName).getThreadPoolType(), ThreadPool.ThreadPoolType.SCALING);
      assertThat(threadPool.executor(threadPoolName), instanceOf(EsThreadPoolExecutor.class));

      // Change settings that doesn't require pool replacement
      Executor oldExecutor = threadPool.executor(threadPoolName);
      clusterSettings.applySettings(
          Settings.builder()
              .put("threadpool." + threadPoolName + ".keep_alive", "10m")
              .put("threadpool." + threadPoolName + ".min", "2")
              .put("threadpool." + threadPoolName + ".size", "15")
              .build());
      assertEquals(
          info(threadPool, threadPoolName).getThreadPoolType(), ThreadPool.ThreadPoolType.SCALING);
      assertThat(threadPool.executor(threadPoolName), instanceOf(EsThreadPoolExecutor.class));
      assertThat(
          ((EsThreadPoolExecutor) threadPool.executor(threadPoolName)).getCorePoolSize(),
          equalTo(2));
      assertThat(
          ((EsThreadPoolExecutor) threadPool.executor(threadPoolName)).getMaximumPoolSize(),
          equalTo(15));
      assertThat(info(threadPool, threadPoolName).getMin(), equalTo(2));
      assertThat(info(threadPool, threadPoolName).getMax(), equalTo(15));
      // Make sure keep alive value changed
      assertThat(info(threadPool, threadPoolName).getKeepAlive().minutes(), equalTo(10L));
      assertThat(
          ((EsThreadPoolExecutor) threadPool.executor(threadPoolName))
              .getKeepAliveTime(TimeUnit.MINUTES),
          equalTo(10L));
      assertThat(threadPool.executor(threadPoolName), sameInstance(oldExecutor));
    } finally {
      terminateThreadPoolIfNeeded(threadPool);
    }
  }
 private synchronized void scheduleSnapshotIfNeeded() {
   if (!shardGateway.requiresSnapshot()) {
     return;
   }
   if (!shardGateway.requiresSnapshotScheduling()) {
     return;
   }
   if (!indexShard.routingEntry().primary()) {
     // we only do snapshotting on the primary shard
     return;
   }
   if (!indexShard.routingEntry().started()) {
     // we only schedule when the cluster assumes we have started
     return;
   }
   if (snapshotScheduleFuture != null) {
     // we are already scheduling this one, ignore
     return;
   }
   if (snapshotInterval.millis() != -1) {
     // we need to schedule snapshot
     if (logger.isDebugEnabled()) {
       logger.debug("scheduling snapshot every [{}]", snapshotInterval);
     }
     snapshotScheduleFuture =
         threadPool.schedule(snapshotInterval, ThreadPool.Names.SNAPSHOT, snapshotRunnable);
   }
 }
 @Override
 protected void doStop() throws ElasticsearchException {
   final boolean setStopped = started.compareAndSet(true, false);
   assert setStopped : "service has already been stopped";
   try {
     transport.stop();
   } finally {
     // in case the transport is not connected to our local node (thus cleaned on node disconnect)
     // make sure to clean any leftover on going handles
     for (Map.Entry<Long, RequestHolder> entry : clientHandlers.entrySet()) {
       final RequestHolder holderToNotify = clientHandlers.remove(entry.getKey());
       if (holderToNotify != null) {
         // callback that an exception happened, but on a different thread since we don't
         // want handlers to worry about stack overflows
         threadPool
             .generic()
             .execute(
                 new Runnable() {
                   @Override
                   public void run() {
                     holderToNotify
                         .handler()
                         .handleException(
                             new TransportException(
                                 "transport stopped, action: " + holderToNotify.action()));
                   }
                 });
       }
     }
   }
 }
 private void handleTransportDisconnect(DiscoveryNode node) {
   if (!latestNodes.nodeExists(node.id())) {
     return;
   }
   NodeFD nodeFD = nodesFD.remove(node);
   if (nodeFD == null) {
     return;
   }
   if (!running) {
     return;
   }
   nodeFD.running = false;
   if (connectOnNetworkDisconnect) {
     try {
       transportService.connectToNode(node);
       nodesFD.put(node, new NodeFD());
       threadPool.schedule(pingInterval, ThreadPool.Names.SAME, new SendPingRequest(node));
     } catch (Exception e) {
       logger.trace("[node  ] [{}] transport disconnected (with verified connect)", node);
       notifyNodeFailure(node, "transport disconnected (with verified connect)");
     }
   } else {
     logger.trace("[node  ] [{}] transport disconnected", node);
     notifyNodeFailure(node, "transport disconnected");
   }
 }
 @Inject
 public LocalTransport(
     Settings settings,
     ThreadPool threadPool,
     Version version,
     NamedWriteableRegistry namedWriteableRegistry,
     CircuitBreakerService circuitBreakerService) {
   super(settings);
   this.threadPool = threadPool;
   this.version = version;
   int workerCount =
       this.settings.getAsInt(
           TRANSPORT_LOCAL_WORKERS, EsExecutors.boundedNumberOfProcessors(settings));
   int queueSize = this.settings.getAsInt(TRANSPORT_LOCAL_QUEUE, -1);
   logger.debug("creating [{}] workers, queue_size [{}]", workerCount, queueSize);
   final ThreadFactory threadFactory =
       EsExecutors.daemonThreadFactory(this.settings, LOCAL_TRANSPORT_THREAD_NAME_PREFIX);
   this.workers =
       EsExecutors.newFixed(
           LOCAL_TRANSPORT_THREAD_NAME_PREFIX,
           workerCount,
           queueSize,
           threadFactory,
           threadPool.getThreadContext());
   this.namedWriteableRegistry = namedWriteableRegistry;
   this.circuitBreakerService = circuitBreakerService;
 }
 @AfterClass
 public static void stopThreadPool() {
   if (threadPool != null) {
     threadPool.shutdownNow();
     threadPool = null;
   }
 }
 AckCountDownListener(
     AckedClusterStateTaskListener ackedTaskListener,
     long clusterStateVersion,
     DiscoveryNodes nodes,
     ThreadPool threadPool) {
   this.ackedTaskListener = ackedTaskListener;
   this.clusterStateVersion = clusterStateVersion;
   this.nodes = nodes;
   int countDown = 0;
   for (DiscoveryNode node : nodes) {
     if (ackedTaskListener.mustAck(node)) {
       countDown++;
     }
   }
   // we always wait for at least 1 node (the master)
   countDown = Math.max(1, countDown);
   logger.trace(
       "expecting {} acknowledgements for cluster_state update (version: {})",
       countDown,
       clusterStateVersion);
   this.countDown = new CountDown(countDown);
   this.ackTimeoutCallback =
       threadPool.schedule(
           ackedTaskListener.ackTimeout(),
           ThreadPool.Names.GENERIC,
           new Runnable() {
             @Override
             public void run() {
               onTimeout();
             }
           });
 }
 protected void handleResponse(
     Channel channel, StreamInput buffer, final TransportResponseHandler handler) {
   final TransportResponse response = handler.newInstance();
   response.remoteAddress(
       new InetSocketTransportAddress((InetSocketAddress) channel.getRemoteAddress()));
   response.remoteAddress();
   try {
     response.readFrom(buffer);
   } catch (Throwable e) {
     handleException(
         handler,
         new TransportSerializationException(
             "Failed to deserialize response of type [" + response.getClass().getName() + "]", e));
     return;
   }
   try {
     if (handler.executor() == ThreadPool.Names.SAME) {
       //noinspection unchecked
       handler.handleResponse(response);
     } else {
       threadPool.executor(handler.executor()).execute(new ResponseHandler(handler, response));
     }
   } catch (Throwable e) {
     handleException(handler, new ResponseHandlerFailureTransportException(e));
   }
 }
  protected String handleRequest(
      Channel channel, StreamInput buffer, long requestId, Version version) throws IOException {
    final String action = buffer.readString();

    final NettyTransportChannel transportChannel =
        new NettyTransportChannel(transport, action, channel, requestId, version);
    try {
      final TransportRequestHandler handler = transportServiceAdapter.handler(action);
      if (handler == null) {
        throw new ActionNotFoundTransportException(action);
      }
      final TransportRequest request = handler.newInstance();
      request.remoteAddress(
          new InetSocketTransportAddress((InetSocketAddress) channel.getRemoteAddress()));
      request.readFrom(buffer);
      if (handler.executor() == ThreadPool.Names.SAME) {
        //noinspection unchecked
        handler.messageReceived(request, transportChannel);
      } else {
        threadPool
            .executor(handler.executor())
            .execute(new RequestHandler(handler, request, transportChannel, action));
      }
    } catch (Throwable e) {
      try {
        transportChannel.sendResponse(e);
      } catch (IOException e1) {
        logger.warn("Failed to send error message back to client for action [" + action + "]", e);
        logger.warn("Actual Exception", e1);
      }
    }
    return action;
  }
 private static void execute(
     Settings settings,
     BiFunction<Runnable, TimeValue, ScheduledFuture<?>> scheduler,
     Consumer<Throwable> consumer,
     boolean constructionShouldFail,
     Runnable asserts)
     throws InterruptedException {
   assert constructionShouldFail == (consumer != null);
   assert constructionShouldFail == (asserts == null);
   ThreadPool threadPool = null;
   try {
     threadPool =
         new ThreadPool(JvmGcMonitorServiceSettingsTests.class.getCanonicalName()) {
           @Override
           public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, TimeValue interval) {
             return scheduler.apply(command, interval);
           }
         };
     try {
       JvmGcMonitorService service = new JvmGcMonitorService(settings, threadPool);
       if (constructionShouldFail) {
         fail("construction of jvm gc service should have failed");
       }
       service.doStart();
       asserts.run();
       service.doStop();
     } catch (Throwable t) {
       consumer.accept(t);
     }
   } finally {
     ThreadPool.terminate(threadPool, 30, TimeUnit.SECONDS);
   }
 }
  @Inject
  public TransportClientNodesService(
      Settings settings,
      ClusterName clusterName,
      TransportService transportService,
      ThreadPool threadPool,
      Headers headers,
      Version version) {
    super(settings);
    this.clusterName = clusterName;
    this.transportService = transportService;
    this.threadPool = threadPool;
    this.minCompatibilityVersion = version.minimumCompatibilityVersion();
    this.headers = headers;

    this.nodesSamplerInterval =
        this.settings.getAsTime("client.transport.nodes_sampler_interval", timeValueSeconds(5));
    this.pingTimeout =
        this.settings.getAsTime("client.transport.ping_timeout", timeValueSeconds(5)).millis();
    this.ignoreClusterName =
        this.settings.getAsBoolean("client.transport.ignore_cluster_name", false);

    if (logger.isDebugEnabled()) {
      logger.debug("node_sampler_interval[" + nodesSamplerInterval + "]");
    }

    if (this.settings.getAsBoolean("client.transport.sniff", false)) {
      this.nodesSampler = new SniffNodesSampler();
    } else {
      this.nodesSampler = new SimpleNodeSampler();
    }
    this.nodesSamplerFuture =
        threadPool.schedule(
            nodesSamplerInterval, ThreadPool.Names.GENERIC, new ScheduledNodeSampler());
  }
  @AfterMethod
  public void tearDown() {
    serviceA.close();
    serviceB.close();

    threadPool.shutdown();
  }
 private void handleException(final TransportResponseHandler handler, Throwable error) {
   if (!(error instanceof RemoteTransportException)) {
     error = new RemoteTransportException(error.getMessage(), error);
   }
   final RemoteTransportException rtx = (RemoteTransportException) error;
   if (handler.executor() == ThreadPool.Names.SAME) {
     try {
       handler.handleException(rtx);
     } catch (Throwable e) {
       logger.error("failed to handle exception response [{}]", e, handler);
     }
   } else {
     threadPool
         .executor(handler.executor())
         .execute(
             new Runnable() {
               @Override
               public void run() {
                 try {
                   handler.handleException(rtx);
                 } catch (Throwable e) {
                   logger.error("failed to handle exception response [{}]", e, handler);
                 }
               }
             });
   }
 }
 @Override
 public void close(final boolean delete) {
   try {
     Set<Integer> shardIds = shardIds();
     final CountDownLatch latch = new CountDownLatch(shardIds.size());
     for (final int shardId : shardIds) {
       threadPool
           .cached()
           .execute(
               new Runnable() {
                 @Override
                 public void run() {
                   try {
                     deleteShard(shardId, delete, !delete, delete);
                   } catch (Exception e) {
                     logger.warn("failed to close shard, delete [{}]", e, delete);
                   } finally {
                     latch.countDown();
                   }
                 }
               });
     }
     try {
       latch.await();
     } catch (InterruptedException e) {
       throw new ElasticSearchInterruptedException(
           "interrupted closing index [ " + index().name() + "]", e);
     }
   } finally {
     indicesLifecycle.removeListener(cleanCacheOnIndicesLifecycleListener);
   }
 }
Exemple #18
0
 @After
 public void tearDown() throws Exception {
   super.tearDown();
   serviceA.close();
   serviceB.close();
   threadPool.shutdown();
 }
 @Override
 protected void doStart() throws ElasticSearchException {
   this.clusterState = newClusterStateBuilder().blocks(initialBlocks).build();
   this.updateTasksExecutor =
       newSingleThreadExecutor(daemonThreadFactory(settings, "clusterService#updateTask"));
   this.reconnectToNodes =
       threadPool.scheduleWithFixedDelay(new ReconnectToNodes(), reconnectInterval);
 }
    /** Builds a new instance of the transport client. */
    public TransportClient build() {
      Settings settings = InternalSettingsPreparer.prepareSettings(this.settings);
      settings =
          settingsBuilder()
              .put(
                  NettyTransport.PING_SCHEDULE,
                  "5s") // enable by default the transport schedule ping interval
              .put(settings)
              .put("network.server", false)
              .put("node.client", true)
              .put(CLIENT_TYPE_SETTING, CLIENT_TYPE)
              .build();

      PluginsService pluginsService = new PluginsService(settings, null, null, pluginClasses);
      this.settings = pluginsService.updatedSettings();

      Version version = Version.CURRENT;

      final ThreadPool threadPool = new ThreadPool(settings);
      final NetworkService networkService = new NetworkService(settings);
      final SettingsFilter settingsFilter = new SettingsFilter(settings);
      NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry();
      boolean success = false;
      try {
        ModulesBuilder modules = new ModulesBuilder();
        modules.add(new Version.Module(version));
        // plugin modules must be added here, before others or we can get crazy injection errors...
        for (Module pluginModule : pluginsService.nodeModules()) {
          modules.add(pluginModule);
        }
        modules.add(new PluginsModule(pluginsService));
        modules.add(new SettingsModule(this.settings, settingsFilter));
        modules.add(new NetworkModule(networkService, this.settings, true, namedWriteableRegistry));
        modules.add(new ClusterNameModule(this.settings));
        modules.add(new ThreadPoolModule(threadPool));
        modules.add(
            new SearchModule(settings, namedWriteableRegistry) {
              @Override
              protected void configure() {
                // noop
              }
            });
        modules.add(new ActionModule(true));
        modules.add(new CircuitBreakerModule(this.settings));

        pluginsService.processModules(modules);

        Injector injector = modules.createInjector();
        injector.getInstance(TransportService.class).start();
        TransportClient transportClient = new TransportClient(injector);
        success = true;
        return transportClient;
      } finally {
        if (!success) {
          ThreadPool.terminate(threadPool, 10, TimeUnit.SECONDS);
        }
      }
    }
  @Inject
  public SearchService(
      Settings settings,
      ClusterService clusterService,
      IndicesService indicesService,
      IndicesWarmer indicesWarmer,
      ThreadPool threadPool,
      ScriptService scriptService,
      PageCacheRecycler pageCacheRecycler,
      BigArrays bigArrays,
      DfsPhase dfsPhase,
      QueryPhase queryPhase,
      FetchPhase fetchPhase,
      IndicesQueryCache indicesQueryCache) {
    super(settings);
    this.threadPool = threadPool;
    this.clusterService = clusterService;
    this.indicesService = indicesService;
    indicesService
        .indicesLifecycle()
        .addListener(
            new IndicesLifecycle.Listener() {

              @Override
              public void afterIndexDeleted(Index index, @IndexSettings Settings indexSettings) {
                // once an index is closed we can just clean up all the pending search context
                // information
                // to release memory and let references to the filesystem go etc.
                freeAllContextForIndex(index);
              }
            });
    this.indicesWarmer = indicesWarmer;
    this.scriptService = scriptService;
    this.pageCacheRecycler = pageCacheRecycler;
    this.bigArrays = bigArrays;
    this.dfsPhase = dfsPhase;
    this.queryPhase = queryPhase;
    this.fetchPhase = fetchPhase;
    this.indicesQueryCache = indicesQueryCache;

    TimeValue keepAliveInterval = settings.getAsTime(KEEPALIVE_INTERVAL_KEY, timeValueMinutes(1));
    // we can have 5 minutes here, since we make sure to clean with search requests and when
    // shard/index closes
    this.defaultKeepAlive = settings.getAsTime(DEFAULT_KEEPALIVE_KEY, timeValueMinutes(5)).millis();

    Map<String, SearchParseElement> elementParsers = new HashMap<>();
    elementParsers.putAll(dfsPhase.parseElements());
    elementParsers.putAll(queryPhase.parseElements());
    elementParsers.putAll(fetchPhase.parseElements());
    elementParsers.put("stats", new StatsGroupsParseElement());
    this.elementParsers = ImmutableMap.copyOf(elementParsers);

    this.keepAliveReaper = threadPool.scheduleWithFixedDelay(new Reaper(), keepAliveInterval);

    this.indicesWarmer.addListener(new NormsWarmer());
    this.indicesWarmer.addListener(new FieldDataWarmer());
    this.indicesWarmer.addListener(new SearchWarmer());
  }
 private synchronized void onTaskCompletion() {
   if (mustReschedule()) {
     indexService.logger.debug("scheduling {} every {}", toString(), interval);
     this.scheduledFuture = threadPool.schedule(interval, getThreadPool(), BaseAsyncTask.this);
   } else {
     indexService.logger.debug("scheduled {} disabled", toString());
     this.scheduledFuture = null;
   }
 }
  public static void main(String[] args) throws Exception {
    ShardId shardId = new ShardId(new Index("index"), 1);
    Settings settings = EMPTY_SETTINGS;

    //        Store store = new RamStore(shardId, settings);
    Store store = new ByteBufferStore(shardId, settings, null, new ByteBufferCache(settings));
    //        Store store = new NioFsStore(shardId, settings);

    store.deleteContent();

    ThreadPool threadPool = new ScalingThreadPool();
    SnapshotDeletionPolicy deletionPolicy =
        new SnapshotDeletionPolicy(new KeepOnlyLastDeletionPolicy(shardId, settings));
    Engine engine =
        new RobinEngine(
            shardId,
            settings,
            store,
            deletionPolicy,
            new MemoryTranslog(shardId, settings),
            new LogByteSizeMergePolicyProvider(store),
            new ConcurrentMergeSchedulerProvider(shardId, settings),
            new AnalysisService(shardId.index()),
            new SimilarityService(shardId.index()));
    engine.start();

    SimpleEngineBenchmark benchmark =
        new SimpleEngineBenchmark(store, engine)
            .numberOfContentItems(1000)
            .searcherThreads(50)
            .searcherIterations(10000)
            .writerThreads(10)
            .writerIterations(10000)
            .refreshSchedule(new TimeValue(1, TimeUnit.SECONDS))
            .flushSchedule(new TimeValue(1, TimeUnit.MINUTES))
            .create(false)
            .build();

    benchmark.run();

    engine.close();
    store.close();
    threadPool.shutdown();
  }
 IndexWarmer(Settings settings, ThreadPool threadPool, Listener... listeners) {
   super(settings);
   ArrayList<Listener> list = new ArrayList<>();
   final Executor executor = threadPool.executor(ThreadPool.Names.WARMER);
   list.add(new FieldDataWarmer(executor));
   for (Listener listener : listeners) {
     list.add(listener);
   }
   this.listeners = Collections.unmodifiableList(list);
 }
  public void testIndexingThreadPoolsMaxSize() throws InterruptedException {
    String threadPoolName = randomThreadPoolName();
    for (String name : new String[] {ThreadPool.Names.BULK, ThreadPool.Names.INDEX}) {
      ThreadPool threadPool = null;
      try {

        int maxSize = EsExecutors.boundedNumberOfProcessors(Settings.EMPTY);

        // try to create a too-big (maxSize+1) thread pool
        threadPool =
            new ThreadPool(
                Settings.builder()
                    .put("node.name", "testIndexingThreadPoolsMaxSize")
                    .put("threadpool." + name + ".size", maxSize + 1)
                    .build());

        // confirm it clipped us at the maxSize:
        assertEquals(
            maxSize, ((ThreadPoolExecutor) threadPool.executor(name)).getMaximumPoolSize());

        ClusterSettings clusterSettings =
            new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
        threadPool.setClusterSettings(clusterSettings);

        // update it to a tiny size:
        clusterSettings.applySettings(
            Settings.builder().put("threadpool." + name + ".size", 1).build());

        // confirm it worked:
        assertEquals(1, ((ThreadPoolExecutor) threadPool.executor(name)).getMaximumPoolSize());

        // try to update to too-big size:
        clusterSettings.applySettings(
            Settings.builder().put("threadpool." + name + ".size", maxSize + 1).build());

        // confirm it clipped us at the maxSize:
        assertEquals(
            maxSize, ((ThreadPoolExecutor) threadPool.executor(name)).getMaximumPoolSize());
      } finally {
        terminateThreadPoolIfNeeded(threadPool);
      }
    }
  }
    @Override
    public void clusterChanged(ClusterChangedEvent event) {
      if (!master && event.localNodeMaster()) {
        master = true;
        for (LocalNodeMasterListener listener : listeners) {
          Executor executor = threadPool.executor(listener.executorName());
          executor.execute(new OnMasterRunnable(listener));
        }
        return;
      }

      if (master && !event.localNodeMaster()) {
        master = false;
        for (LocalNodeMasterListener listener : listeners) {
          Executor executor = threadPool.executor(listener.executorName());
          executor.execute(new OffMasterRunnable(listener));
        }
      }
    }
 public void startRecovery(
     final IndexShard indexShard,
     final DiscoveryNode sourceNode,
     final RecoveryListener listener) {
   // create a new recovery status, and process...
   final long recoveryId =
       onGoingRecoveries.startRecovery(
           indexShard, sourceNode, listener, recoverySettings.activityTimeout());
   threadPool.generic().execute(new RecoveryRunner(recoveryId));
 }
  public void testUpdateSettingsCanNotChangeThreadPoolType() throws InterruptedException {
    String threadPoolName = randomThreadPoolName();
    ThreadPool.ThreadPoolType invalidThreadPoolType = randomIncorrectThreadPoolType(threadPoolName);
    ThreadPool.ThreadPoolType validThreadPoolType =
        ThreadPool.THREAD_POOL_TYPES.get(threadPoolName);
    ThreadPool threadPool = null;
    try {
      threadPool =
          new ThreadPool(
              Settings.builder()
                  .put("node.name", "testUpdateSettingsCanNotChangeThreadPoolType")
                  .build());
      ClusterSettings clusterSettings =
          new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS);
      threadPool.setClusterSettings(clusterSettings);

      clusterSettings.applySettings(
          Settings.builder()
              .put("threadpool." + threadPoolName + ".type", invalidThreadPoolType.getType())
              .build());
      fail("expected IllegalArgumentException");
    } catch (IllegalArgumentException e) {
      assertEquals(
          "illegal value can't update [threadpool.] from [{}] to [{"
              + threadPoolName
              + ".type="
              + invalidThreadPoolType.getType()
              + "}]",
          e.getMessage());
      assertThat(
          e.getCause().getMessage(),
          is(
              "setting threadpool."
                  + threadPoolName
                  + ".type to "
                  + invalidThreadPoolType.getType()
                  + " is not permitted; must be "
                  + validThreadPoolType.getType()));
    } finally {
      terminateThreadPoolIfNeeded(threadPool);
    }
  }
  private void performStateRecovery(boolean enforceRecoverAfterTime, String reason) {
    final Gateway.GatewayStateRecoveredListener recoveryListener = new GatewayRecoveryListener();

    if (enforceRecoverAfterTime && recoverAfterTime != null) {
      if (scheduledRecovery.compareAndSet(false, true)) {
        logger.info("delaying initial state recovery for [{}]. {}", recoverAfterTime, reason);
        threadPool.schedule(
            recoverAfterTime,
            ThreadPool.Names.GENERIC,
            () -> {
              if (recovered.compareAndSet(false, true)) {
                logger.info(
                    "recover_after_time [{}] elapsed. performing state recovery...",
                    recoverAfterTime);
                gateway.performStateRecovery(recoveryListener);
              }
            });
      }
    } else {
      if (recovered.compareAndSet(false, true)) {
        threadPool
            .generic()
            .execute(
                new AbstractRunnable() {
                  @Override
                  public void onFailure(Exception e) {
                    logger.warn("Recovery failed", e);
                    // we reset `recovered` in the listener don't reset it here otherwise there
                    // might be a race
                    // that resets it to false while a new recover is already running?
                    recoveryListener.onFailure("state recovery failed: " + e.getMessage());
                  }

                  @Override
                  protected void doRun() throws Exception {
                    gateway.performStateRecovery(recoveryListener);
                  }
                });
      }
    }
  }
  @AfterMethod
  public void tearDown() throws Exception {
    replicaEngine.close();
    storeReplica.close();

    engine.close();
    store.close();

    if (threadPool != null) {
      threadPool.shutdownNow();
    }
  }