コード例 #1
0
  @SuppressWarnings({"ConstantConditions", "unchecked"})
  @Test
  @BadApple
  public void testIndexShardLifecycleLeak() throws Exception {

    client()
        .admin()
        .indices()
        .prepareCreate("test")
        .setSettings(
            ImmutableSettings.builder()
                .put("index.number_of_shards", 1)
                .put("index.number_of_replicas", 0))
        .execute()
        .actionGet();

    client().admin().cluster().prepareHealth().setWaitForGreenStatus().execute().actionGet();

    IndicesService indicesService = cluster().getInstance(IndicesService.class);
    IndexService indexService = indicesService.indexServiceSafe("test");
    Injector indexInjector = indexService.injector();
    IndexShard shard = indexService.shardSafe(0);
    Injector shardInjector = indexService.shardInjector(0);

    performCommonOperations();

    List<WeakReference> indexReferences = new ArrayList<WeakReference>();
    List<WeakReference> shardReferences = new ArrayList<WeakReference>();

    // TODO if we could iterate over the already created classes on the injector, we can just add
    // them here to the list
    // for now, we simple add some classes that make sense

    // add index references
    indexReferences.add(new WeakReference(indexService));
    indexReferences.add(new WeakReference(indexInjector));
    indexReferences.add(new WeakReference(indexService.mapperService()));
    for (DocumentMapper documentMapper : indexService.mapperService()) {
      indexReferences.add(new WeakReference(documentMapper));
    }
    indexReferences.add(new WeakReference(indexService.aliasesService()));
    indexReferences.add(new WeakReference(indexService.analysisService()));
    indexReferences.add(new WeakReference(indexService.fieldData()));
    indexReferences.add(new WeakReference(indexService.queryParserService()));

    // add shard references
    shardReferences.add(new WeakReference(shard));
    shardReferences.add(new WeakReference(shardInjector));

    indexService = null;
    indexInjector = null;
    shard = null;
    shardInjector = null;

    client().admin().indices().prepareDelete().execute().actionGet();

    for (int i = 0; i < 100; i++) {
      System.gc();
      int indexNotCleared = 0;
      for (WeakReference indexReference : indexReferences) {
        if (indexReference.get() != null) {
          indexNotCleared++;
        }
      }
      int shardNotCleared = 0;
      for (WeakReference shardReference : shardReferences) {
        if (shardReference.get() != null) {
          shardNotCleared++;
        }
      }
      logger.info(
          "round {}, indices {}/{}, shards {}/{}",
          i,
          indexNotCleared,
          indexReferences.size(),
          shardNotCleared,
          shardReferences.size());
      if (indexNotCleared == 0 && shardNotCleared == 0) {
        break;
      }
    }

    // Thread.sleep(1000000);

    for (WeakReference indexReference : indexReferences) {
      assertThat(
          "dangling index reference: " + indexReference.get(), indexReference.get(), nullValue());
    }

    for (WeakReference shardReference : shardReferences) {
      assertThat(
          "dangling shard reference: " + shardReference.get(), shardReference.get(), nullValue());
    }
  }