private void unexport(ClusterMemoryPool pool) {
   try {
     String objectName =
         ObjectNames.builder(ClusterMemoryPool.class, pool.getId().toString()).build();
     exporter.unexport(objectName);
   } catch (JmxException e) {
     log.error(e, "Failed to unexport pool %s", pool.getId());
   }
 }
 @PreDestroy
 public void destroy() {
   for (QueueKey key : queryQueues.keySet()) {
     String objectName =
         ObjectNames.builder(QueryQueue.class, key.getQueue().getTemplate())
             .withProperty("expansion", key.getName())
             .build();
     mbeanExporter.unexport(objectName);
   }
 }
  private synchronized void updatePools(Map<MemoryPoolId, Integer> queryCounts) {
    // Update view of cluster memory and pools
    List<MemoryInfo> nodeMemoryInfos =
        nodes
            .values()
            .stream()
            .map(RemoteNodeMemory::getInfo)
            .filter(Optional::isPresent)
            .map(Optional::get)
            .collect(toImmutableList());

    long totalClusterMemory =
        nodeMemoryInfos
            .stream()
            .map(MemoryInfo::getTotalNodeMemory)
            .mapToLong(DataSize::toBytes)
            .sum();
    clusterMemoryBytes.set(totalClusterMemory);

    Set<MemoryPoolId> activePoolIds =
        nodeMemoryInfos
            .stream()
            .flatMap(info -> info.getPools().keySet().stream())
            .collect(toImmutableSet());

    // Make a copy to materialize the set difference
    Set<MemoryPoolId> removedPools = ImmutableSet.copyOf(difference(pools.keySet(), activePoolIds));
    for (MemoryPoolId removed : removedPools) {
      unexport(pools.get(removed));
      pools.remove(removed);
    }
    for (MemoryPoolId id : activePoolIds) {
      ClusterMemoryPool pool =
          pools.computeIfAbsent(
              id,
              poolId -> {
                ClusterMemoryPool newPool = new ClusterMemoryPool(poolId);
                String objectName =
                    ObjectNames.builder(ClusterMemoryPool.class, newPool.getId().toString())
                        .build();
                try {
                  exporter.export(objectName, newPool);
                } catch (JmxException e) {
                  log.error(e, "Error exporting memory pool %s", poolId);
                }
                return newPool;
              });
      pool.update(nodeMemoryInfos, queryCounts.getOrDefault(pool.getId(), 0));
    }
  }
 private List<QueryQueue> getOrCreateQueues(
     Session session, Executor executor, List<QueryQueueDefinition> definitions) {
   ImmutableList.Builder<QueryQueue> queues = ImmutableList.builder();
   for (QueryQueueDefinition definition : definitions) {
     String expandedName = definition.getExpandedTemplate(session);
     QueueKey key = new QueueKey(definition, expandedName);
     if (!queryQueues.containsKey(key)) {
       QueryQueue queue =
           new QueryQueue(executor, definition.getMaxQueued(), definition.getMaxConcurrent());
       if (queryQueues.putIfAbsent(key, queue) == null) {
         // Export the mbean, after checking for races
         String objectName =
             ObjectNames.builder(QueryQueue.class, definition.getTemplate())
                 .withProperty("expansion", expandedName)
                 .build();
         mbeanExporter.export(objectName, queue);
       }
     }
     queues.add(queryQueues.get(key));
   }
   return queues.build();
 }