All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hubspot.singularity.SingularityManagedThreadPoolFactory Maven / Gradle / Ivy

package com.hubspot.singularity;

import static com.google.common.base.Preconditions.checkState;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.hubspot.singularity.async.ExecutorAndQueue;
import com.hubspot.singularity.config.SingularityConfiguration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

@Singleton
public class SingularityManagedThreadPoolFactory {
  private final AtomicBoolean stopped = new AtomicBoolean();
  private final List executorPools = new ArrayList<>();

  private final long timeoutInMillis;

  @Inject
  public SingularityManagedThreadPoolFactory(
    final SingularityConfiguration configuration
  ) {
    this.timeoutInMillis =
      TimeUnit.SECONDS.toMillis(configuration.getThreadpoolShutdownDelayInSeconds());
  }

  public synchronized ExecutorService get(String name) {
    checkState(!stopped.get(), "already stopped");
    ExecutorService service = Executors.newCachedThreadPool(
      new ThreadFactoryBuilder().setNameFormat(name + "-%d").build()
    );
    executorPools.add(service);
    return service;
  }

  public synchronized ExecutorService get(String name, int maxSize) {
    checkState(!stopped.get(), "already stopped");
    ExecutorService service = Executors.newFixedThreadPool(
      maxSize,
      new ThreadFactoryBuilder().setNameFormat(name + "-%d").build()
    );
    executorPools.add(service);
    return service;
  }

  public synchronized ExecutorAndQueue get(String name, int maxSize, int queueSize) {
    checkState(!stopped.get(), "already stopped");
    LinkedBlockingQueue queue = new LinkedBlockingQueue(queueSize);
    ExecutorService service = new ThreadPoolExecutor(
      maxSize,
      maxSize,
      0L,
      TimeUnit.MILLISECONDS,
      queue,
      new ThreadFactoryBuilder().setNameFormat(name + "-%d").build()
    );
    executorPools.add(service);
    return new ExecutorAndQueue(service, queue, queueSize);
  }

  public synchronized ExecutorService getSingleThreaded(String name) {
    checkState(!stopped.get(), "already stopped");
    ExecutorService service = Executors.newSingleThreadExecutor(
      new ThreadFactoryBuilder().setNameFormat(name + "-%d").build()
    );
    executorPools.add(service);
    return service;
  }

  public void stop() throws Exception {
    if (!stopped.getAndSet(true)) {
      if (timeoutInMillis == 0) {
        executorPools.forEach(ExecutorService::shutdownNow);
      } else {
        executorPools.forEach(ExecutorService::shutdown);

        long timeoutLeftInMillis = timeoutInMillis;

        for (ExecutorService service : executorPools) {
          final long start = System.currentTimeMillis();

          if (!service.awaitTermination(timeoutLeftInMillis, TimeUnit.MILLISECONDS)) {
            return;
          }

          timeoutLeftInMillis -= (System.currentTimeMillis() - start);
        }
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy